一尘不染

为什么不可能覆盖仅getter的属性并添加setter?[关闭]

c#

为什么不允许以下C#代码:

public abstract class BaseClass
{
    public abstract int Bar { get;}
}

public class ConcreteClass : BaseClass
{
    public override int Bar
    {
        get { return 0; }
        set {}
    }
}

CS0546’ConcreteClass.Bar.set’:无法覆盖,因为’BaseClass.Bar’没有可覆盖的集合访问器


阅读 313

收藏
2020-05-19

共1个答案

一尘不染

因为Baseclass的作者已明确声明Bar必须是只读属性。推导打破合同并使其可读写是没有意义的。

我在这一点上与Microsoft合作。
假设我是一位新程序员,被告知要针对Baseclass派生进行编码。我写的东西假定Bar不能被写入(因为Baseclass明确声明它是一个get
only属性)。现在,根据您的推导,我的代码可能会损坏。例如

public class BarProvider
{ BaseClass _source;
  Bar _currentBar;

  public void setSource(BaseClass b)
  {
    _source = b;
    _currentBar = b.Bar;
  }

  public Bar getBar()
  { return _currentBar;  }
}

由于不能按照BaseClass接口设置Bar,BarProvider认为缓存是安全的事情-
因为Bar不能修改。但是,如果在派生中可以设置set,则如果有人在外部修改_source对象的Bar属性,则此类可以提供陈旧的值。关键是“
要开放,避免做鬼sneak的事情和让人惊讶的事情

更新Ilya Ryzhenkov问:“为什么接口不遵循相同的规则?” 嗯..我想到这变得更加泥泞。
接口是一个合同,上面写着“期望实现具有名为Bar的读取属性”。 个人而言
,如果看到接口,则不太可能将其假设为只读。当我在接口上看到get-only属性时,我将其读取为“任何实现都会公开此属性Bar”……在它单击的基类上,因为“
Bar是只读属性”。当然,从技术上讲,您并没有违反合同。因此,您在某种意义上是正确的。.最后,我要说:“使误解变得越来越难”。

2020-05-19