Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whats the reasoning behind not allowing a derived class's concrete property that implements an interface's interface property?

Tags:

c#

.net

Here is a very simple example.

public interface IMyInterfaceProperty
{
}

public class MyProperty : IMyInterfaceProperty
{
}

public interface IMyInterface
{
    IMyInterfaceProperty SomeProperty { get; set; }
}

public class MyClass : IMyInterface
{
    public MyProperty SomeProperty { get; set; }
}

In this example MyProperty is derived from IMyInterfaceProperty but is not allowed. What was the thought process behind not allowing this to compile?

Program.MyClass does not implement interface member Program.IMyInterface.SomeProperty. Program.MyClass.SomeProperty cannot implement Program.IMyInterface.SomeProperty because it does not have the matching return type of Program.IMyInterfaceProperty.

like image 713
Erik Philips Avatar asked Jan 17 '23 22:01

Erik Philips


2 Answers

Because it's not type safe.

If MyClass implements IMyInterface, then an instance of MyClass needs to be able to work in an IMyInterface variable (Liskov Substitution Principle). Let's see what that means:

In addition to the types you've defined, we also assume:

public class EvilProperty : IMyInterfaceProperty {}

public static class X
{
    public static void EvilMethod(IMyInterface a, IMyInterfaceProperty b)
    {
        a.SomeProperty = b;
    }
}

Now, here's the call (brace yourself!):

X.EvilMethod(new MyClass(), new EvilProperty());

See what will happen? The method will assign the instance of EvilProperty to the MyClass instance's SomeProperty, but that property expects a MyProperty, and EvilProperty doesn't inherit from MyProperty.

like image 107
phoog Avatar answered Jan 21 '23 13:01

phoog


Even the following is not allowed:

public interface IMyInterface
{
    IMyInterfaceProperty SomeProperty { get; set; }
    MyProperty SomeProperty { get; set; }
}

I think the reason is that members with the same signatures are not allowed in the type. And return value is not considered here:

The signature of a method specifically does not include the return type, nor does it include the params modifier that may be specified for the right-most parameter.

(from http://msdn.microsoft.com/en-us/library/aa691131(v=vs.71).aspx. Though it is for VS2003, I don't think that has been changed since those times :) )

like image 40
the_joric Avatar answered Jan 21 '23 12:01

the_joric