【问题标题】:How to make partial virtual property?如何制作部分虚拟财产?
【发布时间】:2010-12-15 08:20:21
【问题描述】:

设计——完美世界

我有一个带有属性 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 的启发 :-)。

【问题讨论】:

    标签: c# inheritance properties


    【解决方案1】:
    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; }
        }
    }
    

    【讨论】:

    • 关键的“新”!魔鬼总是在细节中;-)
    • 只是为了检查这不是我还不知道的技巧:这与在W 中引入新属性相同,对吧? A.ValueW.Value 没有关系,并且做A aw = new W(); aw.Value = 42 不会调用W 中定义的setter。
    • @TheFogger 正确; aw.Value = 42 甚至不应该编译,因为它的类型是 A
    • 视情况而定,如果它在家庭中,它将编译。最好完全摆脱 setter。
    猜你喜欢
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多