Col*_*son 168 c# generics covariance
<out T>
和之间有什么区别<T>
?例如:
public interface IExample<out T>
{
...
}
Run Code Online (Sandbox Code Playgroud)
与
public interface IExample<T>
{
...
}
Run Code Online (Sandbox Code Playgroud)
Ree*_*sey 198
out
泛型中的关键字用于表示接口中的类型T是协变的.有关详细信息,请参阅协方差和逆变.
经典的例子是IEnumerable<out T>
.由于IEnumerable<out T>
是协变的,您可以执行以下操作:
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
Run Code Online (Sandbox Code Playgroud)
如果这不是协变的话,上面的第二行将失败,即使逻辑上它应该起作用,因为字符串派生自对象.之前在通用接口方差加入到C#和VB.NET(.NET 4的与VS 2010),这是一个编译时错误.
在.NET 4之后,IEnumerable<T>
被标记为协变,并成为IEnumerable<out T>
.由于IEnumerable<out T>
只使用其中的元素,并且从不添加/更改它们,因此将可枚举的字符串集合视为可枚举的对象集合是安全的,这意味着它是协变的.
这样的类型不适用IList<T>
,因为IList<T>
有一个Add
方法.假设允许这样做:
IList<string> strings = new List<string>();
IList<object> objects = strings; // NOTE: Fails at compile time
Run Code Online (Sandbox Code Playgroud)
然后你可以打电话:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
Run Code Online (Sandbox Code Playgroud)
当然,这会失败 - 所以IList<T>
不能标记为协变.
btw还有一个选项in
- 比较接口之类的东西. IComparer<in T>
例如,工作方式相反.你可以IComparer<Foo>
直接使用IComparer<Bar>
if 作为if Bar
的子类Foo
,因为IComparer<in T>
接口是逆变的.
o0o*_*o0o 59
为了便于记住in
和out
关键字(也是协方差和逆变)的使用,我们可以将继承映像为包装:
String : Object
Bar : Foo
Run Code Online (Sandbox Code Playgroud)
Jod*_*ell 48
考虑,
class Fruit {}
class Banana : Fruit {}
interface ICovariantSkinned<out T> {}
interface ISkinned<T> {}
Run Code Online (Sandbox Code Playgroud)
和功能,
void Peel(ISkinned<Fruit> skinned) { }
void Peel(ICovariantSkinned<Fruit> skinned) { }
Run Code Online (Sandbox Code Playgroud)
接受的函数ICovariantSkinned<Fruit>
将能够接受ICovariantSkinned<Fruit>
或ICovariantSkinned<Bananna>
因为ICovariantSkinned<T>
是协变接口而且Banana
是一种类型Fruit
,
接受的功能ISkinned<Fruit>
只能接受ISkinned<Fruit>
.
Jam*_*rld 32
" out T
"表示类型T
是"协变".这限制T
为仅作为泛型类,接口或方法的方法中的返回(出站)值出现.这意味着您可以将类型/接口/方法强制转换为具有超类型的等效项T
.
例如ICovariant<out Dog>
可以演员ICovariant<Animal>
.
从您发布的链接....
对于泛型类型参数,out关键字指定type参数是协变的.
编辑:再次,从您发布的链接
有关更多信息,请参阅协方差和逆变(C#和Visual Basic).http://msdn.microsoft.com/en-us/library/ee207183.aspx