C# 跨接口合同 我认为接口不仅是一组成员,而且是一个“契约”,它强制实现实现接口文档中规定的限制。例如: interface IDevice { bool IsActive { get; } int Address { get; } /// <summary> /// Raised when (IsActive == false) /// and device was activated /// </summary> event Action Activated; /// <summary> /// Raised when (IsActive == true) /// and device was deactivated /// </summary> event Action Deactivated; /// <summary> /// Raised when (IsActive == false) /// and Address was changed /// </summary> event Action<int> AddressChanged; }
现在,C# 跨接口合同 我认为接口不仅是一组成员,而且是一个“契约”,它强制实现实现接口文档中规定的限制。例如: interface IDevice { bool IsActive { get; } int Address { get; } /// <summary> /// Raised when (IsActive == false) /// and device was activated /// </summary> event Action Activated; /// <summary> /// Raised when (IsActive == true) /// and device was deactivated /// </summary> event Action Deactivated; /// <summary> /// Raised when (IsActive == false) /// and Address was changed /// </summary> event Action<int> AddressChanged; },c#,oop,interface,documentation,design-by-contract,C#,Oop,Interface,Documentation,Design By Contract,现在,IDevice看起来像: interface IDevice : IAddressee { bool IsActive { get; } /// <summary> /// Raised when (IsActive == false) /// and device was activated /// </summary> event Action Activated; /// <summary>
IDevice
看起来像:
interface IDevice : IAddressee
{
bool IsActive { get; }
/// <summary>
/// Raised when (IsActive == false)
/// and device was activated
/// </summary>
event Action Activated;
/// <summary>
/// Raised when (IsActive == true)
/// and device was deactivated
/// </summary>
event Action Deactivated;
}
interface IDevice:iadressee
{
布尔是活动的{get;}
///
///当(IsActive==false)时引发
///设备被激活了
///
事件动作激活;
///
///当(IsActive==true)时引发
///设备被停用
///
事件动作停用;
}
正如您所看到的,IDevice
的契约解除了一个条件:AddressChanged
事件只应在设备未激活时引发(IsActive==false
)
我无法在iadressee
界面中记录它,因为它不依赖于IDevice
并且可以存在非设备实现
这种情况正常吗?您将如何强制IDevice
实现正确的行为
我不熟悉合同的概念,因此请消除我的幻想和疑虑在这种情况下,抽象条件就可以了。它们表达的内容可能取决于顶级类中不可用的信息。该条件随后以适合特定后代的方式实现。在你的例子中
interface IAddressee
{
int Address { get; }
/// <summary>
/// Can Address be changed?
/// </summary>
bool IsAddessChangeable { get; };
/// <summary>
/// Raised when (IsAddessChangeable == true)
/// and Address was changed
/// </summary>
event Action<int> AddressChanged;
}
interface-iadressee
{
int地址{get;}
///
///地址可以更改吗?
///
布尔是可更改的{get;};
///
///当(IsAddeSChangeable==true)时引发
///地址也变了
///
事件动作地址改变;
}
在实现
IDevice
的类中,查询isaddeschangeable
将返回IsActive==false
,在其他类中-该值取决于所需的语义。您只是问如何注释接口,以便有人知道它们是如何工作的吗?我之所以问你,是因为除了关于IDevices地址更改特殊条件的评论外,你没有丢失任何东西。在这两种情况下都不能“强制”实现按照您的要求进行操作。但是,也许您可以在AddressChanged事件处理程序中使用“Debug.Assert(!sender is IDevice | | sender.IsActive)”。注释是告知合同实现的唯一方法,因此,是的,我想问如何注释它。但我也想知道我是否用正确的方式来思考它。我认为,更换所有处理程序是个坏主意。我认为“我该如何评论这件事?”的答案是非常主观的。我想我会把评论放在IDevice声明的旁边,因为“:iadressee”是相关的部分。但是,您是否真的期望拥有实现IAddressee而不是IDevice的对象?如果你不这样做,我会认为不管怎样,让IDevice保持原样会更好。您的IDevice侦听器不必注册已激活/已停用的处理程序。换句话说,我不认为你通过分解AddressChanged得到了什么,除非你有实现IAddressee的非IDevice对象。这个例子使用了conditionIsActive==false
,在这个例子之后的讨论使用了它的倒数IsActive==true
。其中一个可能需要更正。@AlexanderKogtenkov首先更正了,我认为这违反了ISP,因为iadressee
必须依赖于它不使用的成员:isaddeschangeable
。但后来我把所有事件都改成了方法,一切都变得清晰了<代码>收件人由于地址更改
合同,用户确实依赖于isaddeschange
。我建议您用实例扩展您的答案,用方法替换事件(请参见编辑)@astef我回滚了您的编辑,因为这是对已接受答案中代码的重大更改。我建议你先从作者那里获得关于你的编辑的反馈,或者发布一个单独的答案。
interface IAddressee
{
int Address { get; }
/// <summary>
/// Can Address be changed?
/// </summary>
bool IsAddessChangeable { get; };
/// <summary>
/// Raised when (IsAddessChangeable == true)
/// and Address was changed
/// </summary>
event Action<int> AddressChanged;
}