具有自定义Comparer 的OrderBy的Linq语法

任何给定的Linq表达式都有两种格式,带有自定义排序比较器:

格式1

var query = source .Select(x => new { x.someProperty, x.otherProperty } ) .OrderBy(x => x, new myComparer()); 

格式2

 var query = from x in source orderby x // comparer expression goes here? select new { x.someProperty, x.otherProperty }; 

题:
第二种格式的order-by表达式的语法是什么?

不是问题:
如何使用自定义比较器,如第一种格式所示。

奖金积分:
上面列出的两种Linq格式是否有实际的正式名称?

第二种格式的order-by表达式的语法是什么?

它不存在。 从orderby子句文档 :

您还可以指定自定义比较器。 但是,它仅可通过使用基于方法的语法获得。


如何以第一种格式使用自定义比较器。

你写得正确。 您可以在编写时传递IComparer


上面列出的两种Linq格式是否有实际的正式名称?

格式1称为“基于方法的语法”( 来自上一个链接 ),格式2是“查询表达式语法”(从此处 )。

如何使用自定义比较器,如第一种格式所示。

您不能以该格式使用自定义比较器。

上面列出的两种Linq格式是否有实际的正式名称?

格式1是方法语法,格式2是“查询语法”,

题:

这在查询语法中是不可能的,因为没有重载。

不是问题:

只有在使用reflection来比较对象时才能使用具有匿名类型的比较器,最好使用类型化实现进行比较。

如果您不想创建类型化实现,可以使用Tuple

 var query = source .Select(x => new Tuple(x.someProperty, x.otherProperty)) .OrderBy(x => x, new MyComparer()); public class MyComparer : IComparer> { public int Compare(Tuple x, Tuple y) { return x.Item1.CompareTo(y.Item1); } } 

奖金积分:

  • 查询语法或理解语法
  • 方法语法或扩展方法语法

这不一定是回答原始问题,但它在某种程度上扩展了概述的一些可能性。 我发布这个以防其他人遇到类似的问题。 此处发布的解决方案概述了按选项的通用订单,这在其他情况下可能很有用。 在此示例中,我想按不同的属性对文件列表进行排序。

 ///  /// Used to create custom comparers on the fly ///  ///  public class GenericCompare : IComparer { // Function use to perform the compare private Func ComparerFunction { set; get; } // Constructor public GenericCompare(Func comparerFunction) { ComparerFunction = comparerFunction; } // Execute the compare public int Compare(T x, T y) { if (x == null || y == null) { // These 3 are bell and whistles to handle cases where one of the two is null, to sort to top or bottom respectivly if (y == null && x == null) { return 0; } if (y == null) { return 1; } if (x == null) { return -1; } } try { // Do the actual compare return ComparerFunction(x, y); } catch (Exception ex) { // But muffle any errors System.Diagnostics.Debug.WriteLine(ex); } // Oh crud, we shouldn't be here, but just in case we got an exception. return 0; } } 

然后在实施中……

  GenericCompare DefaultComparer; if (SortOrder == SORT_FOLDER_FILE) { DefaultComparer = new GenericCompare((fr1, fr2) => { return fr1.FullName.ToLower().CompareTo(fr2.FullName.ToLower()); }); } else if (SortOrder == SORT_SIZE_ASC) { DefaultComparer = new GenericCompare((fr1, fr2) => { return fr1.Length.CompareTo(fr2.Length); }); } else if (SortOrder == SORT_SIZE_DESC) { DefaultComparer = new GenericCompare((fr1, fr2) => { return fr2.Length.CompareTo(fr1.Length); }); } else { DefaultComparer = new GenericCompare((fr1, fr2) => { return fr1.Name.ToLower().CompareTo(fr2.Name.ToLower()); }); } var ordered_results = (new DirectoryInfo(@"C:\Temp")) .GetFiles() .OrderBy(fi => fi, DefaultComparer); 

最大的优点是你不需要为每个订单创建一个新的类,你可以只连接一个新的lambda。 显然,这可以通过各种方式进行扩展,因此希望它可以在某个时间帮助某个人。