【问题标题】:Why interface is not implemented: List<string> is ICollection<string>为什么没有实现接口: List<string> 是 ICollection<string>
【发布时间】:2020-10-27 09:15:37
【问题描述】:

考虑一下 C# sn-p:

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

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

为什么实施不实施合同?

List&lt;string&gt; 实现ICollection&lt;string&gt;

真实案例

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

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

【问题讨论】:

  • 只是因为Derived&lt;MyType&gt;Base&lt;MyType&gt;无关。无论如何,即使它:接口是一个合同,必须完全履行。所以你的签名必须与界面完全匹配。
  • C# 9 引入covariant return types,可能对您的案例有所帮助

标签: c# inheritance interface breeze-sharp


【解决方案1】:

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

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

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

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

正如界面所述,list 现在是ICollection&lt;string&gt; 类型。没有办法调用任何List&lt;T&gt;s 成员,除非您明确地转换为List&lt;string&gt;,这与抽象和接口的观点相矛盾。通过这种方式,您可以轻松地通过更新版本来交换实际实现,而无需客户做任何事情。

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

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

【讨论】:

  • 那么为这两个类找到接口的真正问题没有解决方案?
  • @GioviQ 您可以使用显式接口实现,请参阅我的编辑
猜你喜欢
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
  • 2016-07-25
  • 2018-10-23
  • 2014-07-22
  • 2017-05-08
  • 1970-01-01
  • 2011-03-10
相关资源
最近更新 更多