0

Consider the C# snippet:

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

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

Why Implementation does not implement Contract?

List<string> implements ICollection<string>

Real case

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

How to find an interface that both classes implement?

GioviQ
  • 75
  • 1
  • 9
  • 3
    simply because `Derived` has nothing to do with `Base`. Anyway even if it **would**: the interface is a contract, which must be fullfilled completely. So your signature has to match the interface exactly. – MakePeaceGreatAgain Oct 27 '20 at 09:20
  • 2
    C# 9 introduces [covariant return types](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/covariant-returns), it might be helpful for your case – Pavel Anikhouski Oct 27 '20 at 09:41

1 Answers1

1

An interface is a contract for consumers of your code. In your case that contract states: "there is a member called Coll which is of type ICollection<string>".

Implementations of your interface therefor have to follow it - that is they have to implement members exactly the same way the contract defines them - this is you need the exact same signature as of the interface.

Furthermore there´s absoluteley no way for a consumer to determine if or if not the member is of a more deerived type. In fact consumers shouldn´t care for that at all. That´s the point of an interface - to have an abstracttion about your actual implementations. So even if your implementation would work, clients have no way to use it:

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

As the interface states, list now is of type ICollection<string>. There´s no way to call any of List<T>s members, unless you explicitely cast to List<string>, which contradicts the point of abstractions and interfaces. This way you can easily exchange the actual implementation by a newer version for example, without clients need to do anything.

EDIT: to get an interface for both your classes you can use an explicit 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; }
}
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111