Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement interface using concrete implementations of abstract interface members

Tags:

c#

Is there a specific reason why the following is not possible?

class ClassOfInts : IHaveInts
{
    public MyInt IntHolder { get; }
    // This solves my use case but i'm unsure why this is necessary
    // IInt IHaveInts.IntHolder { get => IntHolder; }
}

interface IHaveInts
{
    IInt IntHolder { get; }
}


class MyInt : IInt
{
    public int TheInt { get; }
}

interface IInt
{
    int TheInt { get; }
}

I would think that the above code successfully implements IHaveInts since MyInt implements IInt.

like image 294
Gunnar Már Óttarsson Avatar asked Dec 07 '25 18:12

Gunnar Már Óttarsson


1 Answers

Is there a specific reason why the following is not possible?

Well, the short answer is: "because the C# specification doesn't allow it". Longer answers typically involve some amount of speculation as to what was in the thought process of the C# language designers. That makes such questions primarily opinion based.

However, they did make a deliberate choice that interface members have to be implemented precisely as declared, and that choice is why you can't do that. A likely reason behind that choice is that they would have to special-case read-only properties, because allowing the property to be implemented that way for a writeable property would be unsafe. Were they to allow that, you'd be able to assign any IInt value to the property which expects only MyInt values.

That said, depending on what you're actually trying to do, you might be able to use generic type variance to support your scenario. This will compile fine:

public class ClassOfInts : IHaveInts<MyInt>
{
    public MyInt IntHolder { get; }
}

public interface IHaveInts<out T> where T : IInt
{
    T IntHolder { get; }
}

Declared that way, the following works fine:

static void M()
{
    IHaveInts<IInt> haveInts = new ClassOfInts();
}

This is semantically equivalent to what you were originally trying to do. That is, when using the interface type, you have a property of type IInt, but you want to implement that property with a member that returns a value of type MyInt.

like image 78
Peter Duniho Avatar answered Dec 15 '25 14:12

Peter Duniho



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!