首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >List Generics -隐式转换

List Generics -隐式转换
EN

Stack Overflow用户
提问于 2011-08-01 20:43:43
回答 5查看 960关注 0票数 7

我的目标是.NET 3.5。假设我有一个类Bob,它是SubBob的抽象基类。

我可以声明:

代码语言:javascript
复制
Bob b = new SubBob();

但我不能这么做:

代码语言:javascript
复制
 // compliation error - can't convert
BindingList<Bob> myList = new BindingList<SubBob>(); 

我的猜测是BindingList不希望您这样做,因为它必须知道位于右侧的类型与位于左侧的类型具有相同的内存布局。SubBob的尺寸可能比鲍勃的大。

有没有一种方法可以进行隐式转换,或者需要强制转换?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-08-01 20:53:48

简短的回答

通过实例化BindingList<SubBob>,您可以将其限制为使用SubBob和更具体的类型(例如SubSubBob)。

如果您希望Bob也适用于此,请将myList声明为您希望支持的最不特定类型的的列表

代码语言:javascript
复制
BindingList<Bob> myList = new BindingList<Bob>(); 

(或者,更方便的是,)

代码语言:javascript
复制
var myList = new BindingList<Bob>(); 

解释

它与内存无关(BindingList只包含对对象的引用,并且所有引用的大小都相同),相反,它与您将引入的逻辑不一致有关。

如果这样的代码是可能的,您将能够任意地打破类型限制

代码语言:javascript
复制
BindingList<Animal> myList = new BindingList<Cat>(); 
myList.Add(new Dog()); // bang!

myList是一个Cat列表,你希望它如何处理一个Dog

编译器不会知道有问题,它会很高兴地编译你的代码。当这段代码运行时会发生什么?一个例外?但泛型正是为了解决类型安全问题而引入的。

关于协方差和逆方差的一个附注

在.NET 4.0中,为委托和接口添加了generic covariance and contravariance是正确的(不是为类添加的)。例如,IEnumerable是协变的,这意味着您可以将它赋给派生比T少的任何类型的变量

代码语言:javascript
复制
IEnumerable<Cat> cats = new List<Cat> { new Cat("Hudson"), new Cat("Crookshanks") };
IEnumerable<Animal> animals = cats; // sequence of cats is sequence of animals

但这只是可能的,因为IEnumerable<out T>保证它只返回 T (关键字out),而从不接受。如果它接受T作为参数,它将打开上述问题的大门。因此,ICollection不是协变的。

以类似的方式,一些接口保证它们只返回关键字T (T),并且永远不会返回 it。这样的接口被称为逆变量,并允许赋值给具有更具体T的变量

代码语言:javascript
复制
IComparer<Animal> animalComparer = // ...
IComparer<Dog> dogComparer = animalComparer; // comparer of animals is comparer of dogs
票数 6
EN

Stack Overflow用户

发布于 2011-08-01 20:47:49

与您的案例相关的,特别是

您在这里处理的是contravariance,而一个类只能支持协方差或逆方差IEnumerable<T>支持协方差。

它的签名是IEnumerable<out T>,所以它支持T中类的继承类。

通用中的

不幸的是,这在.NET 3.5中不可用。

它是在.NET 4中作为Covariance and Contravariance引入的。

这就是a FAQ on the subject at MSDN。以下是摘录:

代码语言:javascript
复制
// Assignment compatibility. 
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type. 
object obj = str;

// Covariance. 
IEnumerable<string> strings = new List<string>();

// Contravariance.           
// Assume that I have this method: 
// static void SetObject(object o) { } 
Action<object> actObject = SetObject;
票数 1
EN

Stack Overflow用户

发布于 2011-08-01 20:53:40

有没有隐式转换的方法,或者是否需要强制转换?

下面应该允许继承Bob的任何类作为Bob添加到列表中。

代码语言:javascript
复制
BindingList<Bob> myList = new BindingList<Bob>();  

你到底想做什么?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6898583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档