问题
Here's my best attempt to recreate the situation.
public interface IFoo
{
}
public class Foo : IFoo { }
public class Bar : IFoo { }
public class CollectionOf<T> : List<IFoo>
{
}
public class Bars : CollectionOf<Bar>
{
}
public class Test
{
public void Test()
{
CollectionOf<IFoo> bars = new Bars();
}
}
Compiler complains on the instantiation. Bars is a collection of IFoos. Is this one of those covariance/contravariance issues?
回答1:
The fix, if there is one would depend on what it is that's not working for you. I can get your example to compile in two ways, either use IEnumerable or define your CollectionOf as an interface with the out generic modifier. Whether either is a fix for you I don't know:
public interface IFoo { }
public class Foo : IFoo { }
public class Bar : IFoo { }
public interface CollectionOf<out T> : IEnumerable<IFoo> { }
public class Bars : CollectionOf<Bar> { }
public class Test
{
public void Test()
{
IEnumerable<IFoo> bars1 = new Bars();
CollectionOf<IFoo> bars2 = new Bars();
}
}
回答2:
Yes.
Think about it for a second; bars should legally be able to hold objects of any type that implement IFoo. However, an object of type Bars can only hold objects of type Bar.
Using your code this would be allowed, which is obviously wrong.
CollectionOf<IFoo> bars = new Bars();
bars.Add( new Foo() ); // Uh oh!
That would effectively break the type safety afforded to you via generics.
回答3:
Yes it is.
If this was allowed, you would be able to place any object into that collection, as long as it implemented the IFoo interface, but that wouldn't be safe for the collection.
Let me illustrate:
var b = new Bars();
CollectionOf<IFoo> bars = b;
bars.Add(Dummy); // implements IFoo, but does not descend from Bar
At this point, what does b contain? An object of type Dummy? That would be bad, and thus this is not allowed in the first place.
来源:https://stackoverflow.com/questions/9203352/generic-collection-collision