不允许派生类的具体属性实现接口属性的原因是什么?(该问题涉及IT技术)

4

这里有一个非常简单的例子。

public interface IMyInterfaceProperty
{
}

public class MyProperty : IMyInterfaceProperty
{
}

public interface IMyInterface
{
    IMyInterfaceProperty SomeProperty { get; set; }
}

public class MyClass : IMyInterface
{
    public MyProperty SomeProperty { get; set; }
}

在这个例子中,MyProperty 是从 IMyInterfaceProperty 派生而来的,但是不被允许。背后的思考过程是什么导致不能编译通过? Program.MyClass 没有实现接口成员 Program.IMyInterface.SomeProperty。因为它没有匹配的返回类型 Program.IMyInterfaceProperty,所以 Program.MyClass.SomeProperty 无法实现 Program.IMyInterface.SomeProperty
2个回答

5

因为它不是类型安全的。

如果MyClass实现了IMyInterface,那么MyClass的一个实例需要能够在一个IMyInterface变量中工作(Liskov替换原则)。 让我们看看这意味着什么:

除了您定义的类型之外,我们还假设:

public class EvilProperty : IMyInterfaceProperty {}

public static class X
{
    public static void EvilMethod(IMyInterface a, IMyInterfaceProperty b)
    {
        a.SomeProperty = b;
    }
}

现在,这里是调用的代码(做好准备!):
X.EvilMethod(new MyClass(), new EvilProperty());

看看会发生什么?该方法将把EvilProperty的实例分配给MyClass实例的SomeProperty,但该属性期望一个MyProperty,而EvilProperty没有继承自MyProperty


4
甚至以下内容也不允许:
public interface IMyInterface
{
    IMyInterfaceProperty SomeProperty { get; set; }
    MyProperty SomeProperty { get; set; }
}

我认为原因是不允许在类型中具有相同签名的成员。而且这里没有考虑返回值:

方法的签名特别不包括返回类型,也不包括可能针对最右边的参数指定的 params 修改符。

(来自http://msdn.microsoft.com/en-us/library/aa691131(v=vs.71).aspx。尽管它是针对VS2003的,但我认为自那时以来并没有改变 :))

要实现的方法应该具有相同的签名和返回值。如果需要不同的返回值,可以使用泛型:T SomeProperty { get; set; } - the_joric
这更多是针对ASP.Net MVC的,因为默认的模型绑定器无法在我的类上创建一个接口来填充它的值(因此在我的构造函数中,我必须手动使用具体类填充我的接口,而不是允许MVC为我实例化该类)。 - Erik Philips

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接