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对象。这个例子使用了condition
IsActive==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;
}