【问题标题】:What exception to throw when a property setter is not allowed?当不允许使用属性设置器时会抛出什么异常?
【发布时间】:2011-11-21 20:56:47
【问题描述】:

我有一个具有虚拟属性的基类:

public virtual string Name { get; set; }

然后我有一个派生类,它只覆盖属性的getter

public override string Name
{
    get { return "Fixed Name"; }
}

问题是这只覆盖了getter。如果有人调用 setter,则基类 setter 会被调用,而调用者不会知道它是无效的。

所以我想我会做这样的事情:

public override string Name
{
    get { return "Fixed Name"; }
    set { throw new Exception(); } //which exception type?
}

所以两个(相关问题):

  1. 有更好的模式供我使用吗?
  2. 如果我应该使用上述模式,应该使用什么异常?

编辑:一个例外优于另一个例外的一些原因是好的。我和我的同事在NotSupportedInvalidOperation 之间有同样的争论。

【问题讨论】:

  • 基类中需要setter有什么原因吗?
  • @DarylTeo 是的,基类需要支持手动设置名称,虽然它可以在构造函数中。

标签: c# .net inheritance properties


【解决方案1】:

抛出NotSupportedException 异常。 引用链接:

有些方法在基类中不受支持,使用 期望这些方法将在派生的 而是上课。派生类可能只实现 基类中的方法,并抛出 NotSupportedException 不支持的方法。

我的观点是InvalidOperationException 不是一个正确的选择。 引用自 MSDN:

方法调用无效时抛出的异常 对象的当前状态。

您的情况与当前状态无关。就是类契约不支持操作。

【讨论】:

  • hm.. 这句话是有道理的,尽管它与我正在做的事情相反。
  • +1 引用是这个问题的确切答案,当我派生的类由于某种原因无法实现抽象方法时,我是如何做到的
  • @Ray - 你做的完全一样。再读一遍:)
  • @Petar:同意 - 删除我的答案。我一直在寻找 UnsupportedOperationException,它在 Java 中是合适的,但在没有找到它之后,我找到了 InvalidOperationException,由于您给出的原因,这是错误的。
【解决方案2】:

它违反了 Liskov 替换原则,这就是为什么它是个坏主意。

【讨论】:

    【解决方案3】:

    如果可以的话,您可以尝试将 setter 移至基类的构造函数并将 setter 设为私有。或者正如 Jon 建议的那样,使用所有实现都支持的 getter 创建抽象基类/接口。

    这将避免引发异常的整个情况。

    【讨论】:

      【解决方案4】:

      如果基类实际上允许设置名称(而不是公开一个不能保证工作的抽象设置器),派生类也应该这样做。如果你想要一个层次结构,其中包含一些可以设置名称的类和一些不能设置名称的类,这两种类都应该继承自抽象 ReadableXX 类,该类具有链接到抽象的非虚拟读写 Name 属性GetNameSetName 方法。它还应该提供一些方法来指示是否支持SetName(例如CanSetName 方法)。该类的只读变体可以定义一个“新的”只读Name 属性,该属性将链接到GetName,并使其SetName 覆盖抛出NotSupportedException。如果该类的规范规定 SetName 仅在 CanSetName 返回 true 时才有效,那么让 SetNameCanSetName 返回 false 的类中抛出异常不会违反 Liskov 替换原则。

      【讨论】:

        【解决方案5】:

        【讨论】:

        • -1 这表明它尚未实现,但将要实现。大多数情况下,这不适合生产
        • 公平点。通常用作代码生成器的默认异常。
        猜你喜欢
        • 2010-10-12
        • 1970-01-01
        • 1970-01-01
        • 2012-08-10
        • 1970-01-01
        • 1970-01-01
        • 2020-12-30
        • 2018-12-01
        • 2013-12-28
        相关资源
        最近更新 更多