Средство сравнения классов : цель существования явных реализаций IComparer.Сравнить

#c# #comparison

#c# #сравнение

Вопрос:

Цель существования — явные реализации IComparer.Сравнить в реализациях Comparer<T> класса. Если я реализовал, по public abstract int Compare (T x, T y) какой причине и где он может использовать вызов int IComparer.Compare (object ObjX, object ObjY) , принимая во внимание, что objX amp; ObjY должно быть возможно привести к типу T (в другом случае будет ArgumentException).

Строка 12 и строка 13 произведут те же действия;

 class Program
{
    static void Main(string[] args)
    {
      IComparer iRefCommon = (IComparer)new BoxLengthFirst();
      object obj1 = new Box(2, 6, 8);
      object obj2 = new Box(10, 12, 14);
      int resulCompare = iRefCommon.Compare((Box)obj1, (Box)obj2); //line12
      resulCompare = (new BoxLengthFirst()).Compare(new Box(2, 6, 8),
             new Box(10, 12, 14)); //line13
    }
}

public class BoxLengthFirst : Comparer<Box> 
{
    public override int Compare(Box x, Box y)
    {
        if (x.Length.CompareTo(y.Length) != 0)
        {
            return x.Length.CompareTo(y.Length);
        }
        .....
        else
        {
            return 0;
        }
    }
}

public class Box : IComparable, IComparable<Box>
{
    public Box(int h, int l, int w)
    {
        this.Height = h;
        this.Length = l;
        this.Width = w;
    }
    public int Height { get; private set; }
    public int Length { get; private set; }
    public int Width { get; private set; }

    public int CompareTo(object obj)
    {
     ....
    }
    public int CompareTo(Box other)
    {
       ....
    }
}
  

Комментарии:

1. Я не совсем понимаю ваш вопрос. Если это: «почему существует не универсальный интерфейс IComparable , когда есть также («лучший»?) Универсальный интерфейс IComparable<T> ?», То ответ, скорее всего: обратная совместимость . Обобщения были введены в C # 2.0. Нестандартная версия предшествует этому и не была «удалена», чтобы не нарушать какой-либо существующий код. — То же самое с IComparer vs IComparer<T> .

2. @Corak Вопрос касался правильной стратегии: например, мне нужно реализовать средство сравнения для некоторого общего класса («новый код»), и в этом случае я буду реализовывать либо интерфейс IComparer<T>, либо средство сравнения классов <T> (средство сравнения <T> более полезно). Если мне нужно реализовать средство сравнения для какого-то неродственного класса (устаревший код), я буду реализовывать либо интерфейс IComparer, либо средство сравнения классов. Я не вижу практической пользы в том, что я буду реализовывать Comparer<T>, и после этого буду использовать для вызова «my Comparer» через «int IComparer». Сравнить (объект objX, объект ObjY) «. Встречались ли вы с такими случаями?

3. @Corak Или в реальной жизни ситуация другая: после реализации Comparer<t> я могу встретиться с soft (классом), который не может использовать IComparer<T>, но может использовать IComparer ? Это очень распространенная ситуация или нет?

4. Обычная стратегия заключается в реализации обоих. Потому что это так просто сделать. Если у вас уже есть универсальная Compare(T a, T b) версия, то реализовать не универсальную версию может быть так же просто, как public int Compare(object a, object b) => Compare(a as T, b as T); . Когда вы наследуете от средства сравнения абстрактных классов <T> , эта «сантехника» уже выполнена за вас. — То же самое касается IComparable vs IComparable<T> . и Equality интерфейсов и аннотаций тоже. Если у вас есть общий, легко получить не общий.

5. Зачем вообще использовать дженерики вместо использования не дженериков, которые работают со «всеми объектами»? Множество причин. Наиболее часто указываемыми являются безопасность типов, повторное использование кода и отсутствие упаковки типов значений. Полный обзор см. В Руководстве Microsoft по программированию по этой теме.

Ответ №1:

Попробуйте выполнить следующее :

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;


namespace ConsoleApplication108
{
    class Program
    {
        static void Main(string[] args)
        {
            Box a = new Box(1, 1, 1);
            Box b = new Box(2, 2, 2);

            int c = a.CompareTo(b);

        }

    }
    public class Box : IComparable
    {
        public Box() { }
        public Box(int h, int l, int w)
        {
            this.Height = h;
            this.Length = l;
            this.Width = w;
        }
        public int Height { get; private set; }
        public int Length { get; private set; }
        public int Width { get; private set; }

        public int CompareTo(object obj)
        {
             return CompareTo((Box)obj);
        }
        public int CompareTo(object obj1, object obj2)
        {
             return ((Box)obj1).CompareTo((Box)obj2);
        }
        public int CompareTo(Box other)
        {
            int results = this.Height.CompareTo(other.Height);
            if (results != 0)
            {
                results = this.Length.CompareTo(other.Length);
                if (results != 0)
                {
                    results = this.Width.CompareTo(other.Width);
                }
            }
            return results;
        }
    }

}
  

Комментарии:

1. Я обновлен, чтобы включить compareTo(объект obj1, объект obj2)

2. В зависимости от вашего класса блока реализации, в случае вашего вызова из класса Program (int c = a.compareTo(b);) будет называться ‘public int compareTo(Box other)’ .

3. …Продолжить в случае вызова (obj b; поле a) будет вызываться в начале «public int compareTo (object obj)» и после «public int compareTo (поле other)». В каком случае будет использоваться ваш дополнительный вариант — public int compareTo(object obj1, object obj2)?

4. Я добавил новый метод, потому что я прочитал ваш запрос, и он хотел два объекта для сравнения. Обычно я использую метод одного объекта, потому что linq OrderBy хочет использовать метод одного объекта, а также.compareTo(b)