Ответ 1
Более подробную информацию можно найти здесь.
out
делает параметр типа ковариантным. То есть вы можете использовать либо тип, либо любые производные типы. Обратите внимание, что out
работает только с дженериками, он имеет другое значение при использовании в сигнатурах методов (хотя вы, вероятно, уже знали это).
Вот пример, взятый с ссылка на страницу:
// Covariant interface.
interface ICovariant<out R> { }
// Extending covariant interface.
interface IExtCovariant<out R> : ICovariant<R> { }
// Implementing covariant interface.
class Sample<R> : ICovariant<R> { }
class Program
{
static void Test()
{
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();
// You can assign istr to iobj because
// the ICovariant interface is covariant.
iobj = istr;
}
}
Как вы можете видеть, out
в сигнатуре интерфейса позволяет
вы должны назначить ICovariant<String>
переменной ICovariant<Object>
, так как String
происходит от Object
. Без ключевого слова out
вы не сможете сделать это, так как типы будут разными.
Подробнее о ковариации (и связанной с этим контравариантности) вы можете прочитать здесь.
Как указывали другие ответы, IEnumerable
был только ковариантным в .NET 4. Попытка написать код, например:
IEnumerable<Object> strings = new List<string>();
будет компилироваться в .NET 4 и более поздних версиях, но не в предыдущих версиях.