Using lambda expression in place of IComparer argument

前端 未结 3 818
余生分开走
余生分开走 2020-12-08 08:57

Is it possible with C# to pass a lambda expression as an IComparer argument in a method call?

eg something like

var x = someIEnumerable.OrderBy(aClas         


        
3条回答
  •  余生分开走
    2020-12-08 09:46

    If you consistently want to compare projected keys (such as a single property), you can define a class that encapsulates all the key comparison logic for you, including null checks, key extraction on both objects, and key comparison using the specified or default inner comparer:

    public class KeyComparer : Comparer
    {
        private readonly Func _keySelector;
        private readonly IComparer _innerComparer;
    
        public KeyComparer(
            Func keySelector, 
            IComparer innerComparer = null)
        {
            _keySelector = keySelector;
            _innerComparer = innerComparer ?? Comparer.Default;
        }
    
        public override int Compare(TSource x, TSource y)
        {
            if (object.ReferenceEquals(x, y))
                return 0;
            if (x == null)
                return -1;
            if (y == null)
                return 1;
    
            TKey xKey = _keySelector(x);
            TKey yKey = _keySelector(y);
            return _innerComparer.Compare(xKey, yKey);
        }
    }
    

    For convenience, a factory method:

    public static class KeyComparer
    {
        public static KeyComparer Create(
            Func keySelector, 
            IComparer innerComparer = null)
        {
            return new KeyComparer(keySelector, innerComparer);
        }
    }
    

    You could then use this like so:

    var sortedSet = new SortedSet(KeyComparer.Create((MyClass o) => o.MyProperty));
    

    You can refer to my blog post for an expanded discussion of this implementation.

提交回复
热议问题