我在有关.NET属性的设计问题。
interface IX
{
Guid Id { get; }
bool IsInvalidated { get; }
void Invalidate();
}
问题:
此接口具有两个只读属性,Id
和IsInvalidated
。但是,它们本身是只读的事实本身并不能保证它们的值将保持不变。
可以说,我的意图是要清楚地表明……
Id
表示一个常量值(因此可以安全地缓存),而IsInvalidated
可能会在IX
对象的生存期内更改其值(因此不应缓存)。
我如何修改interface IX
以使该合同足够明确?
我自己尝试的三种解决方案:
该界面已经过精心设计。调用方法的存在
Invalidate()
使程序员可以推断出类似名称的属性的值IsInvalidated
可能会受到它的影响。仅在方法和属性的命名类似的情况下,此参数才成立。
通过事件增强此接口
IsInvalidatedChanged
:bool IsInvalidated { get; } event EventHandler IsInvalidatedChanged;
…Changed
事件的存在IsInvalidated
表明该属性可能会更改其值,而事件的类似事件的缺失Id
则表明该属性不会更改其值。我喜欢这种解决方案,但其中很多其他的东西可能根本就不会使用。
IsInvalidated
用以下方法替换属性IsInvalidated()
:bool IsInvalidated();
这可能太微妙了。可以暗示每次都会重新计算一个值-如果它是一个常数,则不需要。MSDN主题“在属性和方法之间选择”对此有这样的说明:
在以下情况下,请使用方法而不是属性。[…]每次调用操作都会返回不同的结果,即使参数没有更改。
我希望得到什么样的答案?
我对解决该问题的完全不同的解决方案最感兴趣,并给出了它们如何击败我的上述尝试的解释。
如果我的尝试在逻辑上有缺陷或具有尚未提及的重大缺点,以致仅剩一种解决方案(或没有解决方案),我想听听我哪里做错了。
如果缺陷很小,并且在考虑了多个解决方案后仍然存在,请发表评论。
至少,我希望获得一些反馈,以了解哪种是您首选的解决方案,以及出于何种原因。
class Foo : IFoo { private bool isInvalidated; public bool IsInvalidated { get { return isInvalidated; } } public void Invalidate() { isInvalidated = true; } }
InvalidStateException
s,但我不确定这在理论上是否可行。不过会很好。
IsInvalidated
需要private set
?