0

考虑 C# 片段:

    interface Contract
    {
        ICollection<string> Coll { get; }
    }

    class Implementation : Contract
    {
        public List<string> Coll { get; } //this declaration is mandatory for other reason
    }

为什么实施不实施合同?

List<string>工具ICollection<string>

真实案例

    //Entity Framework 
    public partial class ApplicationUser : IdentityUser<Guid>
    {
      ...
      public virtual ICollection<Message> Messages { get; set; }
    }

    //Breeze.Sharp Entity 
    public partial class ApplicationUser : BaseEntity
    {
      ...
      public NavigationSet<Message> Messages
        {
            get { return GetValue<NavigationSet<Message>>(); }
        }
    }

如何找到两个类都实现的接口?

4

1 回答 1

1

接口是代码使用者的合同。在您的情况下,该合同规定:“有一个名为“Coll类型ICollection<string>”的成员。

因此,您的接口的实现必须遵循它——也就是说,它们必须以与合同定义它们的方式完全相同的方式实现成员——这是您需要与接口完全相同的签名。

此外,消费者绝对没有办法确定该成员是否属于更衍生的类型。事实上,消费者根本不应该关心这一点。这就是接口的重点——对你的实际实现进行抽象。因此,即使的实现可行,客户也无法使用它:

Contract myContrac = new Implementation();
var list myContract.Coll; 

如界面所述,listnow 是ICollection<string>. 除非您明确地转换为 s ,否则无法调用任何List<T>s 成员,List<string>这与抽象和接口的观点相矛盾。例如,通过这种方式,您可以轻松地通过较新版本交换实际实现,而无需客户端执行任何操作。

编辑:要获得两个类的接口,您可以使用显式接口实现:

interface BaseEntity
{
    ICollection<Message> { get; }
}
//Entity Framework 
public partial class ApplicationUser : IdentityUser<Guid>
{
    public virtual ICollection<Message> Messages { get; }
}

//Breeze.Sharp Entity 
public partial class ApplicationUser : BaseEntity
{
    public NavigationSet<Message> Messages
    {
        get { return GetValue<NavigationSet<Message>>(); }
    }
    BaseIntity.ICollection<Message> Messages { get => this.Messages; }
}
于 2020-10-27T09:27:04.520 回答