开发者

SortedSet<T> and anonymous IComparer<T> in the constructor is not working

开发者 https://www.devze.com 2023-01-04 18:57 出处:网络
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:

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)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号