在C#中强制约束泛型类
很简单,为什么这段代码无法编译?
public interface IWorld { }
public class Foo<T> where T : IWorld { }
public void Hello<T>(T t) where T : IWorld
{
Foo<IWorld> bar1 = new Foo<T>(); //fails implicit cast
Foo<IWorld> bar2 = (Foo<IWorld>)new Foo<T>(); //fails explicit cast
}
由于每个T
实现了IWorld
,因此Foo<T>
每个实例都应该匹配Foo<IWorld>
。 为什么不? 有没有办法解决? 我真的不想诉诸仿制药来实现这一点。
T : IWorld
意味着T已经实现了IWorld,并不意味着它只实现了IWorld,EXACTLY就是IWorld。 它也可能已经实现了其他接口。
但是,C#在更高版本中支持这种转换。 请参阅http://msdn.microsoft.com/en-us/library/dd799517.aspx(泛型中的协变和逆变)
你可以先投射物体
Foo<IWorld> bar2 = (Foo<IWorld>)(object)new Foo<T>();
一个更简单的反对意见 - 想象一下,而不是Foo
,这就是说, List
。
将List<T>
转换为List<IWorld>
,我现在可以将一些其他的IWorld
实现对象(比如T2
类型)添加到仅包含T
类型对象的T
。 这应该是无效的。
所以回到你的Foo
对象 - 如果它包含任何期望用类型T
对象调用的方法,我现在可以用任何实现IWorld
对象调用它们 - 即使(想象一下Foo
一个附加类型约束)该对象不会成为Foo
的符合条件的类型。
我在评论的重点是:价值类型。 同样,如果我们用List<T>
- 一个List<T>
进行谈话,这可能会更容易,因为值类型包含没有装箱的值类型。 如果您需要这些相同值的List<IWorld>
,则每个值都必须在添加到列表中之前进行装箱。