@ RenéVogt рад помочь

тим, у нас есть интерфейс как

public interface IEnumerable<out T>
{ /*...*/ }

этосо-вариант вT.

Затем у нас есть другой интерфейс и класс, реализующий его:

public interface ISomeInterface {}
public class SomeClass : ISomeInterface
{}

Теперь ко-дисперсия позволяет нам сделать следующее

IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>();

Так чтоIEnumerable<SomeClass> присваивается к переменной (или параметру метода) типаIEnumerable<ISomeInterface>.

Но если мы попробуем это в общем методе:

public void GenericMethod<T>(IEnumerable<T> p) where T : ISomeInterface
{
    IEnumerable<ISomeInterface> e = p;
    // or
    TestMethod(p);
}
public void TestMethod(IEnumerable<ISomeInterface> x) {}

мы получаемошибка компилятора CS0266 говорит нам, чтоIEnumerable<T> не может быть преобразован вIEnumerable<ISomeInterface>.

Ограничение четко заявляетT происходит отISomeInterface, и с тех порIEnumerable<T> является ко-вариантом вTэто назначение должно работать (как показано выше).

Есть ли техническая причина, почему это не может работать в общем методе? Или что-то, что я пропустил, что делает компилятор слишком дорогим, чтобы понять это?

Ответы на вопрос(1)

Решение Вопроса

Измени свойGenericMethod и добавить общее ограничениеclass:

public void GenericMethod<T>(IEnumerable<T> p) where T : class, ISomeInterface
{
    IEnumerable<ISomeInterface> e = p;
    // or
    TestMethod(p);
}

Ковариация не поддерживает структуры, поэтому нам нужно сказать, что мы хотим использовать только классы.

 Backs27 сент. 2017 г., 17:01
@ RenéVogt рад помочь
 René Vogt27 сент. 2017 г., 16:59
О, бей меня к этому. Теперь я помню, что читал кое-что об этой проблеме структуры / дисперсии несколько дней назад. Спасибо за быстрый ответ.

Ваш ответ на вопрос