- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
<out T>
之间有什么区别?和 <T>
?例如:
public interface IExample<out T>
{
...
}
对比
public interface IExample<T>
{
...
}
最佳答案
out
泛型中的关键字用于表示接口(interface)中的类型 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
- 由比较接口(interface)之类的东西使用。 IComparer<in T>
,例如,以相反的方式工作。您可以使用具体的 IComparer<Foo>
直接作为 IComparer<Bar>
如果Bar
是 Foo
的子类,因为 IComparer<in T>
接口(interface)是逆变。
关于c# - 泛型中的 <out T> 与 <T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10956993/
我是一名优秀的程序员,十分优秀!