Advantages/Disadvantages of different implementations for Comparing Objects

后端 未结 5 661
滥情空心
滥情空心 2021-02-05 09:27

This questions involves 2 different implementations of essentially the same code.

First, using delegate to create a Comparison method that can be used as a parameter whe

5条回答
  •  南旧
    南旧 (楼主)
    2021-02-05 10:13

    Probably the biggest advantage to accepting a Comparison as opposed to an IComparer is the ability to write anonymous methods. If I have, let's say, a List, where MyClass contains an ID property that should be used for sorting, I can write:

    myList.Sort((c1, c2) => c1.ID.CompareTo(c2.ID));
    

    Which is a lot more convenient than having to write an entire IComparer implementation.

    I'm not sure that accepting an IComparer really has any major advantages, except for compatibility with legacy code (including .NET Framework classes). The Comparer.Default property is only really useful for primitive types; everything else usually requires extra work to code against.

    To avoid code duplication when I need to work with IComparer, one thing I usually do is create a generic comparer, like this:

    public class AnonymousComparer : IComparer
    {
        private Comparison comparison;
    
        public AnonymousComparer(Comparison comparison)
        {
            if (comparison == null)
                throw new ArgumentNullException("comparison");
            this.comparison = comparison;
        }
    
        public int Compare(T x, T y)
        {
            return comparison(x, y);
        }
    }
    

    This allows writing code such as:

    myList.BinarySearch(item,
        new AnonymousComparer(x.ID.CompareTo(y.ID)));
    

    It's not exactly pretty, but it saves some time.

    Another useful class I have is this one:

    public class PropertyComparer : IComparer
        where TProp : IComparable
    {
        private Func func;
    
        public PropertyComparer(Func func)
        {
            if (func == null)
                throw new ArgumentNullException("func");
            this.func = func;
        }
    
        public int Compare(T x, T y)
        {
            TProp px = func(x);
            TProp py = func(y);
            return px.CompareTo(py);
        }
    }
    

    Which you can write code designed for IComparer as:

    myList.BinarySearch(item, new PropertyComparer(c => c.ID));
    

提交回复
热议问题