如何制作部分虚拟财产?

时间:2010-12-15 08:20:22

标签: c# inheritance properties

设计 - 在完美的世界中

我有一个带有属性Value的抽象基类A,以及两个派生类W和R.总是可以读取Value(并且方法总是相同的 - 读取存储的值),所以我会把getter直接到A。

然而写入Value并不总是可行的,因此有W和R.W也提供了一个setter,而R没有 - 它只依赖于来自A的特性。

问题是,无论我尝试什么,我都无法在C#中实现这样的设计。我不能覆盖W中的Value属性,因为基类中没有setter(并且没有,因为向基类添加setter意味着它也会“泄漏”到R)。

现实 - 丑陋的解决方法(不读)

我在A中添加了一个引发异常的setter。在W中我覆盖了setter而在R中我什么都不做。

这很丑陋,因为设计,因为R中的setter是公共的,因为现在这样的代码编译:

R reader;
reader.Value = 5;

问题

那么如何在基类中创建一个只有getter的属性,并在派生类中添加一个setter?

故事

因为总有至少一个好奇的灵魂,我解释说 - 那些类是数据持有者/经理。 R类是动态数据“持有者” - 它使用给定的公式计算值(类似于Lazy Eval类)。大多数东西在W和R中很常见 - 过滤值,发送通知等等。唯一的区别是在R中你不能直接设置值,因为公式是单向的(类似于WPF转换器只有一个方法定义,转换)。

解决方案

感谢Marc我解决了这个问题,这里是代码:

  abstract class A {
      public int Value { get { return ... } }
  }

  class R : A { }

  class W : A {
      new public int Value {
          get { return base.Value; }
          set { .... }
      }
  }

与Marc版本的不同之处在于缺少基类中的setter(这是问题的全部要点),与我的解决方法的区别在于隐藏属性,而不是覆盖它。小而重要的一块。

谢谢Marc的启示: - )。

1 个答案:

答案 0 :(得分:7)

abstract class A {
    public int Value {get; protected set;}
}
class R : A { }
class W : A {
    new public int Value {
        get { return base.Value; }
        set { base.Value = value; }
    }
}