为什么不可能覆盖一个getter-only属性并添加一个setter? [英] Why is it impossible to override a getter-only property and add a setter?

查看:83
本文介绍了为什么不可能覆盖一个getter-only属性并添加一个setter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么你认为(或者为什么是好的)Microsoft选择不允许:

  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'没有可覆盖的集合访问器



解决方案

因为Baseclass的作者已经明确声明了Bar必须是只读属性。对于派生违反本合同并使其进行读写的说法,没有任何意义。



我和微软在一起。

假设我是一个新的程序员,被告知要对Baseclass派生进行编码。我写了一些假设Bar不能被写入的东西(因为Baseclass明确地声明它是一个唯一的属性)。
现在随着你的推导,我的代码可能会中断。例如

  public class BarProvider 
{BaseClass _source;
Bar _currentBar;

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

public Bar getBar()
{return _currentBar;由于Bar不能按照BaseClass接口进行设置,BarProvider假定缓存为$是一件安全的事情 - 由于Bar不能被修改。但是如果在派生中设置了可能,如果有人从外部修改了_source对象的Bar属性,则此类可能会提供陈旧的值。要点开放,避免做鬼祟的事情和令人惊讶的人'



更新 Ilya Ryzhenkov问'为什么接口不按照相同的规则玩?
嗯..这样会变得越来越糟糕了。

接口是一个合同,说期望一个实现具有名为Bar的读取属性。个人如果我看到一个接口,我不太可能做这个只读的假设。当我在界面上看到一个get-only属性时,我将它看作任何实现将公开这个属性Bar'...在一个基类上它点击的Bar是一个只读属性。当然技术上你没有打破合同..你在做更多的事情。所以你是对的,在某种意义上,我会说:尽可能的努力让误会出现。


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'.

这篇关于为什么不可能覆盖一个getter-only属性并添加一个setter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆