Будет работать этот код одинаково (универсальный класс с ограничением базового класса по сравнению с неуниверсальным классом «аналог») - PullRequest
1 голос
/ 27 марта 2019

Я тестирую реализацию интерфейса IComparer для моего класса Inventory.У меня есть две версии реализации, будет ли она работать одинаково?(Вопрос 1)

class Inventory
{
    public string name;
    double cost;
    int onhand;
    public Inventory(string n, double c, int h)
    { //...    }
    }
}
class CustomInvComparer : IComparer<Inventory>
    {
        public int Compare(Inventory x, Inventory y)
        {
            return string.Compare(x.name, y.name, StringComparison.Ordinal);
        }
    }
class CompInv<T> : IComparer<T> where T : Inventory
    {
        public int Compare(T x, T y)
        {
            return string.Compare(x.name, y.name, StringComparison.Ordinal);
        }
    }

И почему в случаях реализации интерфейс IComparer для int32 и для строки не работает со «вторыми вариантами» (без комментария будет основная ошибкаCS0701). Я знаю, что «вторые варианты» (закомментированные) неверны с точки зрения синтаксиса «Ограничения на параметры типа (Руководство по программированию в C #)», но я не вижу логической разницы с предыдущим вариантом », где T:Inventory "?(Вопрос 2)

    class CustomStringComparer : IComparer<System.String>
{
    public int Compare(System.String x, System.String y)
    {
        return x.CompareTo(y);
    }
}

//class CompStr<T> : IComparer<T> where T : System.String
//{
//    public int Compare(T x, T y)
//    {
//        return string.Compare(x, y, StringComparison.Ordinal);
//    }
//}

class CustomIntComparer : IComparer<System.Int32>
{
    public int Compare(System.Int32 x, System.Int32 y)
    {
        return x.CompareTo(y);
    }
}

//class CompStr<T> : IComparer<T> where T : System.Int32
//    {
//    public int Compare(T x, T y)
//    {
//        return string.Compare(x, y, StringComparison.Ordinal);
//    }
//}

1 Ответ

0 голосов
/ 11 апреля 2019

У меня есть две версии реализации, будет ли она работать одинаково? (Вопрос 1)

Ваши две IComparer<T> реализации имеют абсолютно одинаковую логику, поэтому в этом смысле они будут работать точно так же. Единственное существенное различие заключается в том, что универсальная версия будет работать не только для сравнения типов Inventory, но и для любого подкласса Inventory.

Поскольку с помощью дисперсии параметров типа в универсальных интерфейсах можно использовать неуниверсальную версию со сценариями, в которых используется подкласс Inventory, это различие не имеет большого практического значения. Вы должны быть в состоянии использовать любой из них в одинаковых ситуациях.

Что касается вашего второго вопроса:

И почему в случаях реализации интерфейс IComparer для int32 и для строки не работает со «вторыми вариантами» (без комментария будет основная ошибка CS0701)

Ответ на этот вопрос правильный в сообщении об ошибке :

Тип, используемый в качестве ограничения, должен быть интерфейсом, незапечатанным классом или параметром типа.

System.String - это запечатанный класс, а System.Int32 - вовсе не класс. Ни один из них не является ни интерфейсом, ни параметром типа. Так что ни одно из них не считается ограничением.

С практической точки зрения: причина, по которой запечатанные классы и типы значений (структуры, то есть что-то вроде System.Int32) не являются допустимыми ограничениями, заключается в том, что они не имеют никакого смысла в качестве ограничения. Ограничение позволяет параметру типа быть типом, который наследует тип ограничения. Но запечатанные классы и типы значений не могут иметь наследуемые типы. Поэтому использование их в качестве ограничения даст нулевую выгоду. В таких ситуациях вы бы точно так же могли пропустить параметр типа и явно использовать этот тип.

...