"出T"与" T"在泛型 [英] "out T" vs. "T" in Generics
问题描述
之间有什么&LT的差异;从T>
和< T>
?例如:
公共接口的IExample<出T>
{
...
}
VS
公共接口的IExample< T>
{
...
}
我从 MSDN 得到的唯一信息是,
您可以在通用接口和委托使用out关键字。
块引用>解决方案的
退出
泛型关键字用于表示,在接口类型T是协变的。请参见协方差和逆变了解详情。典型的例子是
的IEnumerable<出T>
。由于的IEnumerable<出T>
是协变的,你可以做以下内容:的IEnumerable<串GT;串=新的List<串GT;();
IEnumerable的<对象>对象=串;如果这不是协变的,即使在逻辑上它应该工作,因为字符串对象从上面派生的第二行会失败。在泛型接口方差加入到C#和VB.NET(.NET中的4 VS前2010),这是一个编译时错误。
.NET 4后,
的IEnumerable< T>
被标记协变,并成为的IEnumerable<出T>
。由于的IEnumerable<出T>
只使用其中的元素,从不添加/更改它们,它的安全为它治疗字符串枚举集合作为对象的枚举集合,这意味着它的协的这不会与一个类型如
的IList&LT工作; T>
,因为的IList< T>
有添加
方法。想这将被允许:的IList<串GT;串=新的List<串GT;();
IList的<对象>对象=串; //注意:失败在编译时您可以再调用:
objects.Add(新画面()); //这应该工作,因为IList的<对象>应该让我们添加任何** **对象
这会,当然,失败的 - 所以
的IList< T>
不能标记协还有,顺便说一句,在为
选项 - 这是使用之类的东西比较接口。
的IComparer<在T>
,例如,工作方式恰好相反。你可以用一个具体的的IComparer<富>
直接作为的IComparer<酒吧GT;
如果酒吧
是富
的子类,因为的IComparer<在T>
界面的逆变的What is the difference between
<out T>
and<T>
? For example:public interface IExample<out T> { ... }
vs.
public interface IExample<T> { ... }
The only info I have gotten from MSDN was that
You can use the out keyword in generic interfaces and delegates.
解决方案The
out
keyword in generics is used to denote that the type T in the interface is covariant. See Covariance and contravariance for details.The classic example is
IEnumerable<out T>
. SinceIEnumerable<out T>
is covariant, you're allowed to do the following:IEnumerable<string> strings = new List<string>(); IEnumerable<object> objects = strings;
The second line above would fail if this wasn't covariant, even though logically it should work, since string derives from object. Before variance in generic interfaces was added to C# and VB.NET (in .NET 4 with VS 2010), this was a compile time error.
After .NET 4,
IEnumerable<T>
was marked covariant, and becameIEnumerable<out T>
. SinceIEnumerable<out T>
only uses the elements within it, and never adds/changes them, it's safe for it to treat an enumerable collection of strings as an enumerable collection of objects, which means its covariant.This wouldn't work with a type like
IList<T>
, sinceIList<T>
has anAdd
method. Suppose this would be allowed:IList<string> strings = new List<string>(); IList<object> objects = strings; // NOTE: Fails at compile time
You could then call:
objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object
This would, of course, fail - so
IList<T>
can't be marked covariant.There is also, btw, an option for
in
- which is used by things like comparison interfaces.IComparer<in T>
, for example, works the opposite way. You can use a concreteIComparer<Foo>
directly as anIComparer<Bar>
ifBar
is a subclass ofFoo
, because theIComparer<in T>
interface is contravariant.这篇关于&QUOT;出T&QUOT;与&QUOT; T&QUOT;在泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!