"出T"与" T"在泛型 [英] "out T" vs. "T" in Generics

查看:194
本文介绍了"出T"与" T"在泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

之间有什么&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>. Since IEnumerable<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 became IEnumerable<out T>. Since IEnumerable<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>, since IList<T> has an Add 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 concrete IComparer<Foo> directly as an IComparer<Bar> if Bar is a subclass of Foo, because the IComparer<in T> interface is contravariant.

这篇关于&QUOT;出T&QUOT;与&QUOT; T&QUOT;在泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆