我有一个具有虚拟属性的基类:
public virtual string Name { get; set; }
然后我有一个派生类,它只覆盖属性的getter
public override string Name
{
get { return "Fixed Name"; }
}
问题是这只会覆盖吸气剂。如果有人调用了setter,那么将调用基类setter,调用者将不知道它是无效的。
所以我认为我会做类似的事情:
public override string Name
{
get { return "Fixed Name"; }
set { throw new Exception(); } //which exception type?
}
所以两个(相关问题):
编辑:为什么一个例外优先于另一个例外的一些原因会很好。我的同事和我在NotSupported
和InvalidOperation
之间有相同的论点。
答案 0 :(得分:24)
抛出NotSupportedException例外。 引用链接:
基类中不支持使用的方法 期望这些方法将在派生中实现 而是改为。派生类可能只实现一个子集 来自基类的方法,并抛出NotSupportedException 不受支持的方法。
我的观点是InvalidOperationException不是正确的选择。 从MSDN引用:
方法调用无效时抛出的异常 对象的当前状态。
在你的情况下,目前的状态并不存在。这是班级合同不支持该操作。
答案 1 :(得分:8)
它打破了Liskov替换原则,这就是为什么这是个坏主意。
答案 2 :(得分:4)
如果可以的话,可以尝试将setter移动到基类的构造函数并将setter设为私有。或者,Jon建议使用所有实现中都支持的getter创建抽象基类/接口。
这可以避免抛出异常的整个情况。
答案 3 :(得分:1)
如果基类实际上允许设置名称(而不是暴露不能保证工作的抽象setter),派生类也应该这样做。如果你想要一个包含一些可以设置名称的类的层次结构和一些不能设置它的类,那么这两种类都应该从具有非虚拟读写ReadableXX
属性的抽象Name
类继承。链接到抽象GetName
和SetName
方法。它还应提供一些指示是否支持SetName
的方法(例如CanSetName
方法)。该类的只读变体可以定义一个“新”只读Name
属性,该属性将链接到GetName
,并使其SetName
覆盖抛出NotSupportedException
。如果类的规范说SetName
仅在CanSetName
返回true时才有效,那么让SetName
在CanSetName
返回false的类中抛出异常不会违反Liskov替代原则。
答案 4 :(得分:-3)