Reputation: 73
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.
Upvotes: 7
Views: 131
Reputation: 30698
What is the problem with following
Foo<IWorld> bar1 = new Foo<IWorld>();
What are you trying to achieve?
If you need to pass IWorld
instance, you can safely pass T
, but that is not the case in your code.
EDIT (Based on comments)
To cast to Foo<Array of something>
you can use Cast or OfType depending on your requirement(whether you want to throw or ignore incompatible matches).
If it is .NET 4, it should work automatically due to CoVariance feature.
Upvotes: 0
Reputation: 239646
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.
Upvotes: 1
Reputation: 236208
You can cast to object first
Foo<IWorld> bar2 = (Foo<IWorld>)(object)new Foo<T>();
Upvotes: 1
Reputation: 2500
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)
Upvotes: 1