Дженерики по сравнению с наследованием (когда никакие классы набора не включены),

Это - расширение этого questionand, вероятно, мог бы даже быть дубликат некоторого другого вопроса (Если так, простите мне). Я вижу из MSDN, что дженерики обычно используются с наборами

Наиболее популярный способ использования универсальных классов с наборами как связанные списки, хеш-таблицы, стеки, очереди, деревья и так далее, где операции, такие как добавление и удаление объектов от набора выполняются почти таким же способом независимо от типа хранивших данных.

Примеры, которые я видел также, проверяют вышеупомянутый оператор.

Кто-то может дать допустимое использование дженериков в реальном сценарии, который не включает наборов?

Педантично, я думал о создании примера, который не включает наборы

public class Animal
{
    public void Speak()
    {
       Console.WriteLine("I am an Animal and my type is " + typeof(T).ToString());
    }

    public void Eat()
    {
        //Eat food
    }
}

public class Dog
{
    public void WhoAmI()
    {
        Console.WriteLine(this.GetType().ToString());

    }
}         

и "Животное Собаки типа" будет

Animal magic = new Animal();

Совершенно возможно иметь Dog быть наследованным от Animal (Принятие неуниверсальной версии Animal)Dog:Animal Поэтому Dog Animal

Другим примером я думал, был a BankAccount. Это может быть BankAccount,BankAccount. Это может очень хорошо быть Checking:BankAccount и Savings:BankAccount.

Там какие-либо лучшие практики должны определить, должны ли мы пойти с дженериками или с наследованием?

12
задан Leonardo Pina 15 December 2017 в 12:52
поделиться

5 ответов

Вы, вероятно, получите более точные ответы, но тем не менее учтите следующее: Общие классы подразумевают отношение "из" между универсальным классом и класс параметра.

Все собаки животные, поэтому они разделяют определенные атрибуты / качества со всеми другими животными. Если вы используете наследование, то очень легко реализовать эти общие качества в классе Animal и добавить качества в дочерние классы.Но если вы реализуете его с помощью Animal (Of Dog) , то:

  1. Ваш класс Dog на самом деле не является полностью квалифицированной собакой / животным, поскольку его «животные качества» содержатся в Класс Животных (Of T) . Собака должна быть связана с Животным родительско-дочерними отношениями.
  2. Ваш класс Animal на самом деле не является животным: вы не можете создать какой-либо метод, который принимает Animals в качестве аргумента, потому что вы не можете ссылаться на глобализованный класс Animal (Of T) . На самом деле это семейство классов с общим поведением, а не суперкласс. Вы теряете возможность иметь дело с животными вне класса Animal (Of T) .

Но вот как, ИМХО, вы должны думать о дженериках: Подумайте о классе MedicalDoctor (Of T) . Veterinarian (Of T as Животное) будет унаследован от MedicalDoctor (Of Animal) . DogVeterinarian будет унаследован от Veterinarian (Of Dog) .

Ключевой момент: общий класс и класс параметров не являются тесно связанными и взаимозависимыми, они сосуществуют.

Кстати, если вы хотите увидеть хорошее использование дженериков, не связанных с коллекциями, просто обратите внимание на делегатов, которые у нас есть: Action (Of T), Func (Of TResult), Comparison (Of T), EventHandler (Of TEventArgs), Конвертер (Of TSource, TResult) ... и интерфейсы: IEqualityComparer (Of T), IComparer (Of T) ...

8
ответ дан 2 December 2019 в 20:40
поделиться

Nullable является универсальным, не является классом коллекции, и не может включать наследование, поскольку относится к struct s.

Общие семейства делегатов довольно хороши - EventHandler , Action <...]> , Func <[...]> - гораздо яснее, что такое Func , а не какой-то специальный IdPredicate или что-то еще.

3
ответ дан 2 December 2019 в 20:40
поделиться

Один известный пример реального мира находится в WCF Channel Factory .

Со страницы:

public sealed class Test
{
    static void Main()
    {
        // Code not shown.
    }

    public void Run()
    {
        // This code is written by an application developer.
        // Create a channel factory.
        BasicHttpBinding myBinding = new BasicHttpBinding();

        EndpointAddress myEndpoint = new EndpointAddress("http://localhost/MathService/Ep1");

        ChannelFactory<IMath> myChannelFactory = new ChannelFactory<IMath>(myBinding, myEndpoint);

        // Create a channel.
        IMath wcfClient1 = myChannelFactory.CreateChannel();
        double s = wcfClient1.Add(3, 39);
        Console.WriteLine(s.ToString());
        ((IClientChannel)wcfClient1).Close();

        // Create another channel.
        IMath wcfClient2 = myChannelFactory.CreateChannel();
        s = wcfClient2.Add(15, 27);
        Console.WriteLine(s.ToString());
        ((IClientChannel)wcfClient2).Close();
        myChannelFactory.Close();
    }
}

Я думаю о дженериках так, что они представляют собой тип, на который действует класс. Например, ChannelFactory создает фабрики типа T. Наследование представляет собой иерархические отношения между типами. Собака - это животное, золотистый ретривер - это одновременно и собака, и животное.

3
ответ дан 2 December 2019 в 20:40
поделиться

Используйте наследование в своей ситуации, пожалуйста.
Если класс может быть правильно описан другим классом [например, квадрат можно описать как прямоугольник], квадрат должен наследовать / расширяться от квеста прямоугольника. В противном случае вы попадете в беспорядок.

Используйте GenericClass, чтобы обозначить , что это объект GenericClass типа tType-s Используйте Square: Rectangle, чтобы обозначить , что это квадрат, который также является прямоугольником

в ваш случай:
Используйте слово "собака: животное" для обозначения , это собака, которая также является животным

0
ответ дан 2 December 2019 в 20:40
поделиться

Вы путаете аспект наследования «есть-а» с аспектом «из» универсальных шаблонов.

Универсальные шаблоны подразумевают одинаковость операций между классами, а не только то, что операции существуют полиморфно.

В вашем примере с животными экземпляр Animal не имеет метода WhoAmI , тогда как экземпляр Dog: Animal будет.

1
ответ дан 2 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: