开发者

Why am I getting "The type parameter must be invariantly valid..." error?

开发者 https://www.devze.com 2023-03-08 10:32 出处:网络
I\'ll attempt to shorten this code example: public interface IThing { //...Stuff } public class Thing1 : IThing

I'll attempt to shorten this code example:

public interface IThing
{
    //...  Stuff
}

public class Thing1 : IThing
{  
}

public class Thing2 : IThing
{  
}

public interface IThingView<out T>
{
    ICollection<T> ViewAll();
}

public class ThingView<T> : IThingView<T>
{
    ICollection<T> ViewAll() { return new List<T>(); }  //  There's a big operation here
}

public interface IThingViewerFactory
{
    public IThingView<IThing> Build(string Which);
}

public class ThingViewerFactory
{
    public IThingView<IThing> Build(string Which)
    {
        if(Which.Equals("Thing1") { return new (IThingView<IThing>)new ThingViewer<Thing1>();}
开发者_如何学编程        else { return new (IThingView<IThing>)new ThingViewer<Thing2>();}
    }
}

That's a rough idea of what I'm doing. I have a number of Thing classes that require a viewer, which will follow a comon interface. I'd like a factory to generate these by me passing in a string with the name. I keep getting a compiler error complaining:

Invalid variance: The type parameter 'T' must be invariantly valid on 'IThingView.ViewAll()'. 'T' is covariant.

I realize even if I get this to work, I'll have to do some casting afterwards... I'm fine with that. And I realize this approach is more than likely not necessary. At this point this has become more of a pride/curiosity issue.

Thanks!


You cannot make a covariant ICollection<T>, since it allows you to put Ts into it.

You can make a covariant read-only collection, a contravariant write-only collection, or an invariant read-write collection.
You can't do both, or it wouldn't be typesafe.


To expand on SLaks answer:
To make your code compile, change the return type of ViewAll from ICollection<T> to IEnumerable<T>.

0

精彩评论

暂无评论...
验证码 换一张
取 消