<out T>
和<T>
有什么区别?例如:<out T> vs <T> in Generics
public interface IExample<out T>
{
...
}
与
public interface IExample<T>
{
...
}
我从MSDN得到的唯一信息是,
可以使用了关键字通用接口和委托。
<out T>
和<T>
有什么区别?例如:<out T> vs <T> in Generics
public interface IExample<out T>
{
...
}
与
public interface IExample<T>
{
...
}
我从MSDN得到的唯一信息是,
可以使用了关键字通用接口和委托。
泛型中的out
关键字用于表示接口中的类型T是协变的。详情请参阅Covariance and contravariance。
经典示例是IEnumerable<out T>
。由于IEnumerable<out T>
是协变的,你被允许执行以下操作:
IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;
如果这不是协变上面的第二行会失败,即使在逻辑上它应该工作,因为字符串从对象派生。在variance in generic interfaces被添加到C#和VB.NET(与VS 2010的.NET 4中)之前,这是一个编译时错误。
.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
然后,您可以拨打:
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>
如果Bar
是Foo
一个子类,因为IComparer<in T>
接口逆变。
从您发布的链接....
对于泛型类型参数,out关键字指定的 类型参数是协变。
编辑: 再次,从链接您发布
欲了解更多信息,请参见协变和逆变(C#和Visual Basic)。 http://msdn.microsoft.com/en-us/library/ee207183.aspx
“out T
” 是指式T
是 “协变”。这限制了T
仅出现在泛型类,接口或方法的方法中的返回(出站)值。其含义是您可以将类型/接口/方法强制转换为超类型T
的等效项。
例如ICovariant<out Dog>
可以投射到ICovariant<Animal>
。
我没有意识到'out'强制''T'只能返回,直到我读到这个答案。整个概念现在更有意义! – MarioDS
考虑,
class Fruit {}
class Banana : Fruit {}
interface ICovariantSkinned<out T> {}
interface ISkinned<T> {}
和功能,
void Peel(ISkinned<Fruit> skinned) { }
void Peel(ICovariantSkinned<Fruit> skinned) { }
接受ICovariantSkinned<Fruit>
将能够接受ICovariantSkinned<Fruit>
或ICovariantSkinned<Bananna>
因为ICovariantSkinned<T>
是一个协变接口和Banana
功能是一种类型的Fruit
,
接受功能s ISkinned<Fruit>
将只能接受ISkinned<Fruit>
。
对于记忆的in
容易使用和out
关键字(也协方差和逆变),我们可以图像继承作为包装:
String : Object
Bar : Foo
这使得它很清楚。 – antiduh
这不是错误的方法吗? Contravariance = in =允许使用更少的派生类型来代替更多的派生类型。 /Covariance = out =允许使用更多派生类型来代替派生。 个人,看着你的图,我把它读作的是相反的。 –
很好的例子是的IObservable和IObserver ,定义在mscorlib中的系统ns中。公共接口IObservable 和公共接口IObserver 。同样,IEnumerator的,IEnumerable的 –
VivekDev