Подстановка реализаций в T параметризованного класса типа T - PullRequest
0 голосов
/ 17 мая 2018

Скажем, у меня есть настройки, как

public interface IMyInterface { }

public class MyImplementation : IMyInterface { }

public class MyClass<T> where T : IMyInterface { }

Я понял, что не могу сделать замену, как

var list = new List<MyClass<IMyInterface>>()
{
   new MyClass<MyImplementation>()
}

как я получу ошибку

Невозможно преобразовать из MyClass<MyImplementation> в MyClass<IMyInterface>

Значит ли это, что я пытаюсь сделать, это запах кода?

1 Ответ

0 голосов
/ 17 мая 2018

Это не допускается, потому что T в List<T> является инвариантом.Вот пример, который объяснит:

public interface IFruit
{
    string Name { get; set; }
}

public class Apple : IFruit
{
    public string Name { get; set; }
    public string Color { get; set; }
}

public class Orange : IFruit
{
    public string Name { get; set; }
}

Давайте добавим несколько фруктов в список:

var fruits = new List<IFruit>();
fruits.Add(new Apple());
fruits.Add(new Orange());

Позже в коде вы не знаете, что было добавлено, и вы делаете это:

Orange orange = fruits[0];

Теперь это не скомпилируется, но также не имеет смысла, потому что каждый IFruit не является Apple или Orange.

Что, если компилятор разрешил это?

Если, например, скажем, то, что вы пытаетесь, было разрешено компилятором, например:

// does not compile but let's say it did
List<Apple> fruits = new List<IFruit>(); 

Тогда, если компилятор разрешил это, он должен также разрешить это, поскольку они оба реализуют IFruit:

fruits.Add(new Apple());
fruits.Add(new Orange());

, а затем где-нибудь в коде вы делаете это (так как это список яблок)):

foreach (var thisFruit in fruits)
{
    Console.WriteLine(thisFruit.Color)
}

Crash !! Компилятор не остановил вас в самом начале, и в этот момент вы смотрите на код и он говорит List<Apple>, и вы написали коди все скомпилировано.Во время выполнения о, дерьмо , свойство Color отсутствует, потому что это Orange.

. Поэтому оно не разрешено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...