为什么没有实现接口:List<string> is ICollection<string>

Why interface is not implemented: List<string> is ICollection<string>

考虑 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>>(); }
        }
    }

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

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

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

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

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

如界面所述,list 现在属于 ICollection<string> 类型。没有办法调用 List<T> 的任何成员,除非您显式转换为 List<string>,这与抽象和接口的观点相矛盾。这样您就可以轻松地通过新版本交换实际实现,例如,客户无需执行任何操作。

编辑:要为您的 类 获取接口,您可以使用明确的 interface-implementation:

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; }
}