2012-10-05 45 views
20

有两种格式用于与自定义排序比较器的任何给定的LINQ表达式:LINQ的语法的OrderBy与自定义比较<T>

格式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 }; 

问题:
什么是语法阶通过在第二备考表达T'

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

奖金积分:
是否有上述两种格式的Linq实际,正式的名字呢?

回答

19

什么是用于语法订单通过在第二格式表达?

它不存在。来自orderby clause documentation

您也可以指定自定义比较器。但是,它只能通过使用基于方法的语法来使用。


如何在第一格式使用自定义比较。

你正确地写。你可以像你写的那样通过IComparer<T>


是上述两种格式的Linq有实际的,正式的名字呢?

格式1被称作“基于方法的语法”(from previous link)和格式2是“查询表达式语法”(来自here)。

+1

质量linq链接!尽管基于方法的语法中关于order-by语法的陈述并不是真的应该成为答案的一部分。 :) –

+1

@SteveKonves我只是包括它反正。你可以轻松忽略;) –

2

如何使用自定义比较如图所示为第一格式。

不能在该格式使用自定义比较。

是否存在上述两种Linq格式的实际名称?

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

2

问:

那不是可能的查询语法,因为没有过载。

不是问题:

仅当您使用反射来比较的对象可以使用匿名类型的一个比较器,它更好地使用类型实现了比较。

如果你不希望创建一个类型化的实现,你可以使用一个Tuple

var query = 
    source 
    .Select(x => new Tuple<string, int>(x.someProperty, x.otherProperty)) 
    .OrderBy(x => x, new MyComparer()); 

public class MyComparer : IComparer<Tuple<string, int>> 
{ 
    public int Compare(Tuple<string, int> x, Tuple<string, int> y) 
    { 
    return x.Item1.CompareTo(y.Item1); 
    } 
} 

奖金积分:

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

这并不一定回答原来的问题,但它略微扩展了概述的一些可能性。如果其他人遇到类似问题,我会发布此信息。 此处发布的解决方案概述了在其他情况下可能有用的通用选项。在这个例子中,我想通过不同的属性对文件列表进行排序。

/// <summary> 
/// Used to create custom comparers on the fly 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public class GenericCompare<T> : IComparer<T> 
{ 
    // Function use to perform the compare 
    private Func<T, T, int> ComparerFunction { set; get; } 

    // Constructor 
    public GenericCompare(Func<T, T, int> 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<FileInfo> DefaultComparer; 

     if (SortOrder == SORT_FOLDER_FILE) 
     { 
      DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) => 
      { 
       return fr1.FullName.ToLower().CompareTo(fr2.FullName.ToLower()); 
      }); 
     } 
     else if (SortOrder == SORT_SIZE_ASC) 
     { 
      DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) => 
      { 
       return fr1.Length.CompareTo(fr2.Length); 
      }); 
     } 
     else if (SortOrder == SORT_SIZE_DESC) 
     { 
      DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) => 
      { 
       return fr2.Length.CompareTo(fr1.Length); 
      }); 
     } 
     else 
     { 
      DefaultComparer = new GenericCompare<FileInfo>((fr1, fr2) => 
      { 
       return fr1.Name.ToLower().CompareTo(fr2.Name.ToLower()); 
      }); 
     } 

     var ordered_results = (new DirectoryInfo(@"C:\Temp")) 
       .GetFiles() 
       .OrderBy(fi => fi, DefaultComparer); 

最大的好处是,你再不需要通过案例来为每个订单一个新的类,你可以线了一个新的拉姆达。显然这可以通过各种方式扩展,所以希望它能帮助别人,某个地方,某个时候。