我在有关.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; } }
InvalidStateExceptions,但我不确定这在理论上是否可行。不过会很好。
IsInvalidated需要private set?