<out T>和之间有什么区别<T>?例如:
<out T>
<T>
public interface IExample<out T> { ... }
与
public interface IExample<T> { ... }
out泛型中的关键字用于表示接口中的类型T是协变的。有关详细信息,请参见协方差和协方差。
out
典型的例子是IEnumerable<out T>。由于IEnumerable<out T>是协变的,因此您可以执行以下操作:
IEnumerable<out T>
IEnumerable<string> strings = new List<string>(); IEnumerable<object> objects = strings;
如果这不是协变的,则上面的第二行将失败,即使从逻辑上讲它应该可以工作,因为字符串是从对象派生的。前方差通用接口加入到C#和VB.NET(.NET 4的与VS 2010),这是一个编译时错误。
.NET 4之后,IEnumerable<T>被标记为协变,并成为IEnumerable<out T>。由于IEnumerable<out T>仅使用其中的元素,并且从不添加/更改它们,因此将可枚举的字符串集合视为可枚举的对象集合是安全的,这意味着它是 协变的 。
IEnumerable<T>
IList<T>由于IList<T>具有Add方法,因此不适用于像这样的类型。假设这是允许的:
IList<T>
Add
IList<string> strings = new List<string>(); IList<object> objects = strings; // NOTE: Fails at compile time
然后,您可以致电:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
当然,这将失败-因此IList<T>无法将其标记为协变。
顺便说一句,还有一个选项in-用于比较接口之类的东西。 IComparer<in T>,例如,相反的方式。因为接口是 互变 的,所以可以IComparer<Foo>直接将具体用作IComparer<Bar>if Bar是if 的子类。Foo``IComparer<in T> __
in
IComparer<in T>
IComparer<Foo>
IComparer<Bar>
Bar
Foo``IComparer<in T>