Search code examples
c#interface

Why can interface properties holding an interface type not be implemented with a property holding a concrete type that implements the interface?


When implementing the interface

public interface IMainViewModel
{
    ICommand DoStuffCommand { get; }
}

why is

public class MainViewModel
{
    DelegateCommand DoStuffCommand { get; }
}

with

public class DelegateCommand : ICommand { ... }

not allowed?

Property DoStuffCommand cannot implement property from interface IMainViewModel. Type should be ICommand.


As DelegateCommand implements ICommand, the interface contract guarantees that I am able to use a DelegateCommand exactly the same way I can use any ICommand.


I would like to know why an interface interface-property cannot be implemented with a concrete type, as I wouldn't consider it wrong (or behavior-changing, or functionality-breaking) from my point of view.


Solution

  • Them's just the rules. Outside of generic co-/contra-variance, signatures (including return types1) have to exactly match. You are of course free to add a second method that explicitly implements the interface and just wraps your current DoStuffCommand so that callers who are explicitly working with a MainViewModel object can easily get the DelegateCommand without casting and those using it via an IMainViewModel reference are none the wiser:

    public class MainViewModel : IMainViewModel
    {
        DelegateCommand DoStuffCommand { get; }
        ICommand IMainViewModel.DoStuffCommand => DoStuffCommand;
    }
    

    1One of my personal bugbears is when people state that "return types aren't part of the signature in C#". What they actually mean is "for the purposes of overloading, return types aren't considered". There are plenty of places, such as here, where return types are part of the signature.