假设我从IMyManager继承了一个SetModel。如果我实现它,我通常会写:
using lib.model;
namespace MyComponents
{
public class MyManager:IMyManager
{
public void SetModel(ILibModel model)
{
}
}
}
这对编译器来说很好。
现在让我们说,而不是ILibModel,我传递了一个实现ILibModel的具体类MyModel。
为什么编译器不接受此,而MyModel的类型为ILibModel:
namespace MyComponents
{
public class MyManager:IMyManager
{
public void SetModel(MyModel model) {
}
}
}
答案 0 :(得分:2)
假设MyModel
实现ILibModel
,这不起作用的原因是因为虽然所有MyModel
类型都是ILibModel
类型,但反转并不成立。也就是说,并非所有ILibModel
类型都是MyModel
类型。
接口明确声明它必须采用ILibModel
类型。因此,只需MyModel
的实现就不符合您的接口契约,因为同样实现MyOtherModel
的类型ILibModel
是基于的传递的有效类型你的界面合同。
解决这个问题的唯一方法是在界面上使用泛型。一个例子是:
public interface IMyManager<TModel>
where T : ILibModel
{
void SetModel(TModel model);
}
public class MyManager : IMyManager<MyModel>
{
void SetModel(MyModel model)
{
}
}
但是,您可能遇到与这种系统的协方差和反差的问题。
答案 1 :(得分:1)
因为您正在为SetModel函数提供重载。就编译器而言,也许您希望允许程序员使用具体类型执行更具体的操作,同时使用接口版本执行其他操作。
答案 2 :(得分:1)
因为有人可以稍后写:
((IMyManager)myManager).SetModel(new OtherClassThatImplementsILibModel());
答案 3 :(得分:0)
因为IMyManager
以这种方式定义SetModel
。