Inheriting a method from a class interface by subtyping argument: is it possible?
Let's say I inherit from IMyManager a SetModel. If I implement it I would normally write:
using lib.model;
namespace MyComponents
{
public class MyManager:IMyManager
{
public 开发者_如何学Pythonvoid SetModel(ILibModel model)
{
}
}
}
That's fine for compiler.
Now let's say that instead of ILibModel I pass a concrete class MyModel which implement ILibModel.
Why compiler doesn't accept this whereas MyModel is of type ILibModel :
namespace MyComponents
{
public class MyManager:IMyManager
{
public void SetModel(MyModel model) {
}
}
}
Assuming that MyModel
implements ILibModel
the reason this does not work is because while all MyModel
types are ILibModel
types, the inverse does not hold true. That's to say not all ILibModel
types are MyModel
types.
The interface explicitly states that it MUST take ILibModel
types. So an implementation that takes just MyModel
does not meet your interface contract, because of the fact that a type, say MyOtherModel
that also implements ILibModel
is a valid type to be passed in based on your interface's contract.
The only way around this would be to potentially use generics on the interface. An example being:
public interface IMyManager<TModel>
where T : ILibModel
{
void SetModel(TModel model);
}
public class MyManager : IMyManager<MyModel>
{
void SetModel(MyModel model)
{
}
}
However, you may run into issues with co-variance and contra-variance with such a system.
Because you are supplying an overload for the SetModel function. As far as the compiler is concerned, perhaps you want to allow the programmer to do something more specific with the concrete type, while doing something else with the interface version.
because someone could later write:
((IMyManager)myManager).SetModel(new OtherClassThatImplementsILibModel());
Because the IMyManager
defines SetModel
that way.
精彩评论