Casting constrained generic class in C#

Quite simply, why does this code fail to compile?

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
}

Since every T implements IWorld , every instance of Foo<T> should match Foo<IWorld> . Why not? Is there any way around this? I really don't want to resort to generics to accomplish this.


T : IWorld

means that T has been implemented IWorld and does not mean that it ONLY has implemented IWorld and EXACTLY is IWorld. It may also has been implemented other interfaces.

However, C# supports this cast in it's later versions. Please see http://msdn.microsoft.com/en-us/library/dd799517.aspx (Covariance and Contravariance in Generics)


你可以先投射物体

Foo<IWorld> bar2 = (Foo<IWorld>)(object)new Foo<T>();

An even simpler objection - imagine that instead of Foo , this was, say List .

Having converted your List<T> to a List<IWorld> , I can now add some other IWorld implementing object (say of type T2 ) to a list that is constrained to only contain objects of type T . That shouldn't be valid.

So back to your Foo object - if it contains any methods that expect to be called with objects of type T , I can now call them with any object that implements IWorld - even if (imagine an additional type constraint of Foo ) that object would not be an eligible type for Foo .


My point in the comments re: value types. Again, this may be easier if we talk in terms of List<T> - a List<T> for value types contains the value types without boxing. If you want a List<IWorld> of these same values, each value has to be boxed before it's added to the list.

链接地址: http://www.djcxy.com/p/11634.html

上一篇: C ++等价于NSOperation和NSOperationQueue

下一篇: 在C#中强制约束泛型类