在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> ,则每个值都必须在添加到列表中之前进行装箱。
