How come anonymous functions works as arguments on methods, but not in constructor arguments?
If I create a List<string>
, it has a Sort method with the following signature:
public void Sort(IComparer<T> comparer)
where the following works:
List<string> list = new List<string>();
list.Sort( (a,b) => a.CompareTo(b) );
SortedSet has a constructor with a similar signature:
public SortedSet(IComparer<T> comparer)
but this fails when using an anonymous function in the constructor. The following is not valid:
SortedSet<string> set = new SortedSet<string>( (a, b) => a.CompareTo(b) );
Creating a sorting class works fine as expected:
public class MyCompa开发者_JAVA百科rer : IComparer<string>
{
public int Compare(string a, string b)
{ return a.CompareTo(b); }
}
SortedSet<string> set = new SortedSet<string>( new MyComparer() );
The .NET Framework 4.5 release introduced the factory method Comparer<T>.Create
:
var set = new SortedSet<string>(
Comparer<string>.Create((a, b) => a.CompareTo(b)));
That it is because the constructor accepts an IComparer<T>
(interface), rather than a Comparison<T>
(delegate). Anon-methods / lambdas can support delegates, but not (directly) interfaces. It is pretty easy to wrap, though - for example:
class FuncComparer<T> : IComparer<T>
{
private readonly Comparison<T> comparison;
public FuncComparer(Comparison<T> comparison) {
this.comparison = comparison;
}
public int Compare(T x, T y) {
return comparison(x, y); }
}
Now you can use:
SortedSet<string> set = new SortedSet<string>(
new FuncComparer<string>( (a, b) => a.CompareTo(b) ));
The explanation is great that SortedSet accepts an interface but not a delegate.(But Java does).
Because of that, the .Net guys provide a factory method to create such an object, so you don't need to define a new class for that.
var set = new SortedSet<string>(
Comparer<string>.Create((a, b) => a.CompareTo(b))
);
I your case List.Sort uses this signature
public void Sort(Comparison<T> comparison)
but not this
public void Sort(IComparer<T> comparer)
精彩评论