当不允许属性设置器时抛出什么异常?

发布于 2024-12-05 17:24:58 字数 672 浏览 0 评论 0原文

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

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 之间也有同样的争论。

I have a base class that has a virtual property:

public virtual string Name { get; set; }

then I have a derived class that overrides only the getter of the property

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

The problem is this only overrides the getter. If someone calls the setter the base class setter will get called, and the caller won't know that it's ineffective.

So I thought I'd do something like:

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

So two (related questions):

  1. Is there a better pattern for me to use?
  2. If I should be using the above pattern, what exception to use?

Edit: Some reasons why one exception would be preferred over another would be good. My co-worker and I have had the same argument between NotSupported and InvalidOperation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

与酒说心事 2024-12-12 17:24:58

抛出 NotSupportedException 异常。
引用链接中的内容:

有些方法在基类中不受支持,其中
期望这些方法将在派生中实现
类代替。派生类可能只实现一个子集
基类中的方法,并抛出 NotSupportedException
不支持的方法。

我的意见是 InvalidOperationException 不是正确的选项。
引用自MSDN:

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

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

Throw NotSupportedException exception.
Quote from the link:

There are methods that are not supported in the base class, with the
expectation that these methods will be implemented in the derived
classes instead. The derived class might implement only a subset of
the methods from the base class, and throw NotSupportedException for
the unsupported methods.

My opinion is that InvalidOperationException is not a correct option.
Quote from MSDN:

The exception that is thrown when a method call is invalid for the
object's current state.

There is nothing about current state in your situation. It is that the class contract does not support the operation.

司马昭之心 2024-12-12 17:24:58

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

It breaks Liskov Substitution Principle and that's why it is bad idea.

小耗子 2024-12-12 17:24:58

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

这将避免抛出异常的整个情况。

If you can you could try to move setter to constructor of the base class and make setter private. Or as Jon suggested create abstract base class / interface with getters that are supported in all implementations.

This would avoid the whole situation with throwing exception.

清君侧 2024-12-12 17:24:58

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

If the base class actually allows setting the name (as opposed to exposing an abstract setter which isn't guaranteed to work), derived classes should do so as well. If you want a hierarchy which includes some classes where the name can be set and some where it cannot, both kinds of class should inherit from an abstract ReadableXX class with a non-virtual read-write Name property that chains to abstract GetName and SetName methods. It should also provide some means of indicating whether SetName will be supported (e.g. a CanSetName method). A read-only variant of the class could define a "new" read-only Name property that would chain to GetName, and have its SetName override throw NotSupportedException. If the specification for the class says that SetName will only work if CanSetName returns true, then having SetName throw an exception in classes where CanSetName returns false would not violate the Liskov Substitution Principle.

┊风居住的梦幻卍 2024-12-12 17:24:58

在这里,我会选择 NotImplementedException

Here I'd go for a NotImplementedException.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文