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
转换为 0
和 true
转换为 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?的主要内容,如果未能解决你的问题,请参考以下文章