通过子类型参数从类接口继承方法:是否可能?

时间:2011-04-20 16:37:16

标签: c# .net

假设我从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) {

        }
    }
}

4 个答案:

答案 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