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

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

问题描述

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

公共抽象类 BaseClass{公共抽象 int Bar { get;}}公共类 ConcreteClass : BaseClass{公共覆盖 int Bar{得到 { 返回 0;}放 {}}}

<块引用>

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

解决方案

因为 Baseclass 的作者已经明确声明 Bar 必须是只读属性.推导破坏这个契约并使其可读写是没有意义的.

我在这方面与 Microsoft 合作.
假设我是一名新程序员,他被告知要针对 Baseclass 派生进行编码.我写了一些假设 Bar 不能被写入的东西(因为 Baseclass 明确声明它是一个 get only 属性).现在根据您的推导,我的代码可能会中断.例如

公共类 BarProvider{ 基类 _source;酒吧_currentBar;public void setSource(BaseClass b){_source = b;_currentBar = b.Bar;}公共栏 getBar(){ 返回 _currentBar;}}

因为 Bar 不能按照 BaseClass 接口设置,所以 BarProvider 假设缓存是一件安全的事情 - 因为 Bar 不能修改.但是,如果在派生中可以设置 set,那么如果有人在外部修改了 _source 对象的 Bar 属性,则此类可能会提供陈旧的值.重点是保持开放,避免做鬼鬼祟祟的事情,不要让人们感到惊讶"

更新:Ilya Ryzhenkov 问道:那为什么界面不遵循相同的规则?"嗯..这让我越想越糊涂.
接口是一个约定,它说期望实现具有名为 Bar 的读取属性".个人如果我看到一个接口,我就不太可能做出只读的假设.当我在接口上看到一个 get-only 属性时,我将它读为任何实现都会公开此属性 Bar"...当然,从技术上讲,您并没有违反合同……您做得更多.所以从某种意义上说,你是对的..我会说尽可能避免误解的出现".

Why is the following C# code not allowed:

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天全站免登陆