Почему преобразования из «класса A: IX» в общий «T, где T: IX» не разрешены? - PullRequest
6 голосов
/ 24 февраля 2012

Почему следующее вызывает ошибку компиляции?

interface IX {}
interface IY {}
class XY : IX, IY {}

void Foo<T>() where T : IX, IY
{
    T xy = new XY();
    …   // ^^^^^^^^
}       // error: "Implicit conversion of type 'XY' to 'T' is not possible."

Примечание: Та же ошибка возникнет, если class XY : IX и where T : IX. Тем не менее, я выбрал более сложный пример, потому что более простой пример мог вызвать обходные ответы, такие как «Просто измените тип xy с T на IX» , что не отвечало бы почему это преобразование не удалось.

Ответы [ 2 ]

15 голосов
/ 24 февраля 2012

Потому что, если бы это было законно, вы могли бы сделать это:

interface IPet {} 
interface IMammal {} 
class Dog : IPet, IMammal {}  
class Cat : IPet, IMammal {}
T Foo<T>() where T : IPet, IMammal
{     
  return new Dog();
}
...
Cat cat = Foo<Cat>();  // Assigns a Dog to a variable of type Cat.
12 голосов
/ 24 февраля 2012

Учитывая class ABC : IX, IY { } и Foo<ABC>, ожидаете ли вы тогда использовать new XY()?Потому что у тебя не должно быть этого ожидания.Компилятор тоже не будет.

T не всегда будет XY.T будет ABC, DEF или что-нибудь еще , которое может реализовать ваши два интерфейса и, следовательно, соответствовать вашим ограничениям.XY не может быть преобразовано в ABC, DEF или из любых бесконечных возможностей для T , и поэтому у вас есть сообщение об ошибке: неявное преобразование XY в T невозможно.

Чтобыло бы законно, просто есть new T(), и это верно только , если метод ограничен для его поддержки.

void Foo<T>() where T : IX, IY, new()
{
    T obj = new T();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...