C# LINQ Orderby - 真/假如何影响 orderby?

Posted

技术标签:

【中文标题】C# LINQ Orderby - 真/假如何影响 orderby?【英文标题】:C# LINQ Orderby - How does true/false affect orderby? 【发布时间】:2016-12-29 20:31:27 【问题描述】:

我正在研究一些 LINQ 排序,因为我有一个 Id 列表,我需要按顺序对它们进行排序。但是,某些 id 需要优先于标准排序。

鉴于此 C# 代码(可以粘贴到 .NET Fiddle 中进行测试),排序按我的需要工作,但我不明白为什么 contains 上的 not (!) 运算符给了我顺序正确吗?

我的预期排序输出是 (5, 1, 2, 3, 4, 6, 7, 8, 9)。

如果我的订单中有Contains,它不应该为返回true 的行提供排序优先级吗?相反,它似乎为返回 false 的行提供了排序优先级。

using System.Linq;
using System;

public class Program

  public static void Main()
  
    var numbersToFilterBy = new [] 5, 11, 20;

    var x = new [] new XClass()Id = 1, new XClass()Id = 9, new XClass()Id = 5, new XClass()Id = 3, new XClass()Id = 4, new XClass()Id = 2, new XClass()Id = 6, new XClass()Id = 8, new XClass()Id = 7;

    var trueData = (from data in x
                   orderby !numbersToFilterBy.Contains(data.Id), data.Id
                    select data).ToList();

    foreach(var item in trueData)
        Console.WriteLine(item.Id);
  


public class XClass
    public int Idget;set;
  

为什么会发生这种情况的解释是什么?

【问题讨论】:

【参考方案1】:

让我以List<bool> 为例进行解释。考虑以下 sn-p:

List<bool> BoolList = new List<bool>()  true, false, false, true ;
var opList = BoolList.OrderBy(x => x).ToList();

最后,opList 的值将是 false,false,true,true,这意味着当我们在布尔值列表上应用 OrderBy 时,首先出现 false。这是因为 false 被视为 0 而 true 将被视为 1

在您的情况下,列表首先根据orderby !numbersToFilterBy.Contains(data.Id) 排序为5,1,9,3,4,2,6,8,7,然后data.Id 将为您提供5, 1, 2, 3, 4, 6, 7, 8, 9 的确切结果。

如果你从OrderBy 中删除!,它会给你像1,9,3,4,2,6,8,7,5 这样的第一个排序结果,因为5 的条件为真,因此它将在排序中排在最后。

【讨论】:

正如我在另一个答案中所说,false 永远不会被认为是 0 和 true 1。它的结果与它们相同,但实际上只是它们定义了两个布尔值的排序。这可能是吹毛求疵,但暗示框架可能会将布尔值转换为整数是误导性的,并且并不比他们刚刚定义排序的真实陈述更简单。如果人们习惯于在布尔值和数值之间进行转换的语言,这可能会帮助人们记住顺序。【参考方案2】:

OrderBy 方法将默认按升序对项目进行排序。现在,假设布尔值的数字表示是:

false = 0 true = 1

false 值自然会排在第一位。如果您想颠倒顺序,只需使用descending 关键字:

var trueData = (from data in x
               orderby numbersToFilterBy.Contains(data.Id) descending, data.Id
                select data).ToList();

【讨论】:

在 c# 中,布尔值没有数字表示。它们不是我们假装是布尔值的幕后数字,它们只是布尔值。话虽如此,这种逻辑可以很好地帮助人们记住排序是如何工作的(并且很可能就是为什么 .net 的设计是这样的),但值得记住的是,在 .net 中没有 bool 的数字表示。跨度> @Chris 但是,如果将布尔值转换为整数,则会出现数字结果。这仍然比其他一些语言更多。 @SebastianSchulz:这与布尔值是整数不同。所有CompareTo 方法都返回一个整数。它只是比较的工作方式。有关更多详细信息,请参阅msdn.microsoft.com/en-us/library/…,但基本上 0 表示它们相等,负表示实例位于参数之前,正表示实例位于参数之后。 CompareTo 的结果表示顺序,在排序时不使用它(即它不按 CompareTo 的结果排序,这听起来像是你可能建议的)。 @Chris Convert.ToInt32(Boolean)false 转换为 0true 转换为 1 @JeanHominal:这是真的,但该方法中的代码完全独立于Boolean.CompareTo 中的代码。它不会转换为整数来进行比较,它甚至不在乎您是否可以根据整数来考虑布尔值。它只是定义了在升序排序时 false 出现在 true 之前 - 任何地方都不涉及任何数字。【参考方案3】:

排序与优先级无关——它与序数值有关。您正在对一个布尔值进行升序排列,在这种情况下,false 的序数值低于 true

【讨论】:

【参考方案4】:

基本上,false 早于 true... 将它们视为 false=0,true=1。这与documentation for bool.CompareTo(bool) 一致。

如果您想优先考虑“真”值,只需使用OrderByDescending

【讨论】:

以上是关于C# LINQ Orderby - 真/假如何影响 orderby?的主要内容,如果未能解决你的问题,请参考以下文章

使用 ProGuard,对测试策略有何影响?

IE 对 HTMLDocument 和 HTMLElement 有何影响

静态集合中存储函数对系统有何影响?

iOS 7.1 iBeacon 监控更新对云台有何影响?

复合索引的顺序在 MongoDB 性能方面有何影响?

对常量值使用 def 与 val 有何影响