Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
996 views
in Technique[技术] by (71.8m points)

c# - Why is List<T> not valid on an covariant interface MyInterface<out T>

Follow up question to a previous question, this has been identified as a co-variance issue. Taking this one step further, if I modify IFactory as follows:

class Program
{
    static void Main(string[] args)
    {
        IFactory<IProduct> factory = new Factory();
    }
}

class Factory : IFactory<Product>
{
}

class Product : IProduct
{
}

interface IFactory<out T> where T : IProduct
{
    List<T> MakeStuff();
}

interface IProduct
{
}

I get:

Invalid variance: The type parameter T must be invariantly valid on Sandbox.IFactory.MakeStuff(). T is covariant.

Why is this not invariantly valid? How can/should this be resolved?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The other answers are correct but it is instructive to reason out why the compiler flags this as unsafe. Suppose we allowed it; what could go wrong?

class Sprocket: Product {}
class Gadget : Product {}
class GadgetFactory : IFactory<Gadget> 
{ 
    public List<Gadget> MakeStuff() 
    { 
        return new List<Gadget>() { new Gadget(); } 
    }
}
... later ...
IFactory<Gadget> gf = new GadgetFactory();
IFactory<Product> pf = gf; // Covariant!
List<Product> pl = pf.MakeStuff(); // Actually a list of gadgets
pl.Add(new Sprocket());

and hey, we just added a sprocket to a list that can only contain gadgets.

There is only one place where the compiler can detect the problem, and that's in the declaration of the interface.

Sorry about the somewhat excessively jargonish error message. I couldn't come up with anything better.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...