基于条件的C#Linq OrderBy
我有一个要更改的foreach循环:基于条件的C#Linq OrderBy,c#,linq,C#,Linq,我有一个要更改的foreach循环: foreach(line.OrderBy(x=>x.ColA)中的var行) 如果满足条件,那么我想用可乐代替可乐 我知道可以这样做: var orderLines = new List<OrderLines>(); if (condition) orderLines = lines.OrderBy(x => x.ColB).ToList(); else orderLines = lines.OrderBy(x =>
foreach(line.OrderBy(x=>x.ColA)中的var行)
如果满足条件,那么我想用可乐代替可乐
我知道可以这样做:
var orderLines = new List<OrderLines>();
if (condition)
orderLines = lines.OrderBy(x => x.ColB).ToList();
else
orderLines = lines.OrderBy(x => x.ColA).ToList(); ;
foreach (var line in orderLines)
var orderLines=newlist();
如果(条件)
orderLines=lines.OrderBy(x=>x.ColB.ToList();
其他的
orderLines=lines.OrderBy(x=>x.ColA.ToList();
foreach(订单行中的var行)
但我相信还有一个更优雅的解决方案。安装
NuGet
System.Linq.Dynamic
,您可以将属性
名称作为字符串
传递给OrderBy
,如下所示
用法list.AsQueryable().OrderBy(“PropertyName1排序器,PropertyName排序器”)
。其中PropertyName
将是ColA
ColB
。而SortOrder
将是ASC
DESC
代码>
foreach(行中的变量行。AsQueryable().OrderBy(条件?“ColB”):“ColA”)
对于
.Net Core
安装NuGet
System.Linq.Dynamic.Core
,
foreach(行中的变量行。AsQueryable().OrderBy(条件?“ColB”):“ColA”)
为了获得更好的实践,而不是将
PropertyName
作为字符串提供,请使用nameof(Class.Property)
类似于您的案例nameof(OrderLines.ColA)
。因此,如果更改ColA
属性,它将显示生成错误,并且您不会得到运行时异常
foreach(lines.AsQueryable().OrderBy中的变量行(条件?nameof(OrderLines.ColB):nameof(OrderLines.ColA))
这大概是最好的了
请记住,在lambda表达式的背后,会发生一个绑定到比较器的魔法,其中T取决于要比较的列的类型
使其更简洁可能会降低效率。具体地说,转换和比较字符串会使其速度变慢,并且会给您带来麻烦(整数排序为1,2,3,…10,11,…而字符串排序为“1”,“10”,“11”,“19”,“2”,“20”,“21…”)
“一行”只有在其行为明显的情况下才是优雅的,否则就是模糊的
您的代码很好。(IMO;-)有几种解决方案
(1) 不要在foreach之前执行ToList()
,只创建IEnumerable
IEnumerable<OrderLines> orderLines = condition ?
lines.OrderBy(orderLine => orderLine.ColB) :
lines.OrderBy(orderLine => orderLine.ColA);
foreach(OrderLine orderlLine in orderLines) {...}
但总的来说,它不会为您节省大量代码。唯一的优势是,如果您将在许多方法中使用它。在这种情况下,您希望OrderBy条件的方式的更改只需在一个地方更改。但是,再次强调:如果您希望在一个地方使用它,将其移动到单独的方法可能无法帮助读者理解是什么发生。正如@AlanK所提到的,我们能得到的简化排序规则的最接近的方法是:
Func选择器=(orderLine)=>condition?orderLine.ColB:orderLine.ColA;
List orderLines=lines.OrderBy(选择器);
假设ColA
和ColB
都是相同的数据类型。否则,由于数据类型转换的开销,它将不会有效。取决于条件。它是什么?@juergend条件是检查是什么程序创建了订单行。例如,if(program==“OrderEntry”)然后按B列排序,否则我希望它按A列排序。@萨摩亚程序员执行行。OrderBy(x=>condition?x.ColA:x.ColB)。ToList()
不符合您的要求?@TấnNguyên不抱歉,我试过了,但得到了一个错误,因为ColA是字符串,ColB是int。你这样做的方式很清楚,也可以理解。保持原样。谢谢你的建议@Karan,但我不太喜欢评论@AlanKThanks的评论@ZephyrThanks的评论@Harald copoolse
public static IEnumerable<OrderLine> OrderBy(
this IEnumerable<OrderLine> source,
bool condition)
{
return condition ?
lines.OrderBy(orderLine => orderLine.ColB) :
lines.OrderBy(orderLine => orderLine.ColA);
}
IEnumerable<OrderLine> lines = ...
foreach(var sortedOrderLine in lines.OrderBy(this.CheckBox1.IsChecked))
{
...
}
var result = lines.Where(orderLine => orderLine.Date.Year >= 2020)
.OrderBy(this.checkBox1.IsChecked)
.Select(orderLine => new
{
Id = orderLine.Id,
Price = orderLine.Price,
});