为什么无法覆盖一个getter只读属性,并添加一个setter?属性、getter、setter

2023-09-02 21:10:21 作者:我的世界我做主

为什么你认为(或者,为什么是好事),微软选择不容许:

 公共抽象类的BaseClass
{
    公共抽象INT酒吧{获取;}
}

公共类具体类:BaseClass的
{
    公众覆盖INT酒吧
    {
        {返回0; }
        组 {}
    }
}
 

  

CS0546ConcreteClass.Bar.set:无法重写,因为BaseClass.Bar不具有可重写的set访问

解决方案

由于基类的作者已明确宣布,酒吧已经是一个只读属性。这是没有意义的推导打破这一合同,并使其读写。

我与微软就这一个。 比方说,我是谁被告知code对基类派生一个新的程序员。我写的东西,假设栏不能被写入(因为基类明确指出,这是一个获得唯一的财产)。 现在,你的推导,我的code可能会断裂。例如,

 公共类BarProvider
{BaseClass的_source;
  酒吧_currentBar;

  公共无效的SetSource(BaseClass的B)
  {
    _source = B;
    _currentBar = b.Bar;
  }

  公共酒吧getBar()
  {返回_currentBar; }
}
 
什么是JavaBean以及怎么区分属性和成员变量

由于酒吧不能设置为每BaseClass的接口,BarProvider假定缓存是一种安全的事情 - 因为律师不能修改。但是,如果设置是可能的派生,这个类可以提供过时的值,如果有人修改了的源对象的属性栏外部。点存在的公开,避免做偷偷摸摸的事情,令人惊讶的人*

更新:伊利亚Ryzhenkov问你为什么不打的接口由相同的规则呢?的 嗯..这得到泥泞,我考虑一下。 接口是一个合同,上面写着希望的实现有一个名为酒吧读取属性。 个人我不太可能做出的只读,如果我看到了一个接口,它假设。当我看到一个界面上获取,唯一的财产,我读它作为执行任何可能令该属性栏......在一个基类其卡为酒吧是一个只读属性。当然,在技术上你没有违反合同..你在做多。所以,你是对的在某种意义上..我会关闭说让它尽可能的努力的误解冒出来。

Why do you think (or, why is it good that) Microsoft chose not to allow:

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': cannot override because 'BaseClass.Bar' does not have an overridable set accessor

解决方案

Because the writer of Baseclass has explicitly declared that Bar has to be a read-only property. It doesn't make sense for derivations to break this contract and make it read-write.

I'm with Microsoft on this one. Let's say I'm a new programmer who has been told to code against the Baseclass derivation. i write something that assumes that Bar cannot be written to (since the Baseclass explicitly states that it is a get only property). Now with your derivation, my code may break. e.g.

public class BarProvider
{ BaseClass _source;
  Bar _currentBar;

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

  public Bar getBar()
  { return _currentBar;  }
}

Since Bar cannot be set as per the BaseClass interface, BarProvider assumes that caching is a safe thing to do - Since Bar cannot be modified. But if set was possible in a derivation, this class could be serving stale values if someone modified the source object's Bar property externally. The point being 'Be Open, avoid doing sneaky things and surprising people*'

Update: Ilya Ryzhenkov asks 'Why don't interfaces play by the same rules then?' Hmm.. this gets muddier as I think about it. An interface is a contract that says 'expect an implementation to have a read property named Bar.' Personally I'm much less likely to make that assumption of read-only if I saw an Interface. When i see a get-only property on an interface, I read it as 'Any implementation would expose this attribute Bar'... on a base-class it clicks as 'Bar is a read-only property'. Of course technically you're not breaking the contract.. you're doing more. So you're right in a sense.. I'd close by saying 'make it as hard as possible for misunderstandings to crop up'.