简体   繁体   中英

Why cast of the interface with generic parameter to the same interface with less constraints does not work?

I have the situation:

private IHandle<ICommand> Map<T>(IHandle<T> handle)
    where T : ICommand
{
    return (IHandle<ICommand>) handle;
}

That code gives runtime error. But it seems like IHandle<ICommand> is more generic type than IHandle<T> (because of where T : ICommand constraints). I don't understand why type system can not allow this cast. What should I do with that?

Suppose it was IList<T> instead of IHandle<T> . The following does not work:

    IList<Bar> bars = new List<Bar>();
    IList<Foo> foos = (IList<Foo>)bars;

    public class Foo { }
    public class Bar : Foo { }

Because what would happen if you try to call foos.Add(new Foo()); ? The underlying type is a list of Bar and it cannot accept any old Foo to be added to it, or else it will no longer be a list of Bar s. Someone else may still have a reference to it and will need to iterate through all of its elements as type Bar . So the interface needs to be of the exact type.

That should address the question in the title as to why the cast doesn't work on ordinary interfaces. As to "what you should do with that", if you promise that your interface only outputs things of the generic parameter type and never takes them as input, you can make it work by making the interface covariant, as others have suggested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM