Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于条件的C#Linq OrderBy_C#_Linq - Fatal编程技术网

基于条件的C#Linq OrderBy

基于条件的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循环:

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

  • 使用System.Linq.Dynamic添加
  • foreach(行中的变量行。AsQueryable().OrderBy(条件?“ColB”):“ColA”)

  • 对于
    .Net Core
    安装
    NuGet
    System.Linq.Dynamic.Core

  • 使用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,
                      });