Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can derived C# interface properties override base interface properties with the same name?

I'm trying to create an interface inheritance system that uses the same property but always of a further derived type. So the base property should be somehow overridden or hidden by the deriving interface.

Take, for instance, two interfaces, Man and Woman, that derive into Husband and Wife, also interfaces. Man and Husband interfaces both have a "sweetheart" property, while Woman and Wife have a "darling" property. Now, the Man's "sweetheart" property is of type Woman, while the Husband's same "sweetheart" property should be a Wife (derived from Woman). And the same with the Woman and Wife's "darling" property.

public interface Man // base interface for Husband
{
    Woman sweetheart { get; set; }
}

public interface Woman // base interface for Wife
{
    Man darling { get; set; }
}

public interface Husband : Man // extending Man interface
{
    new Wife sweetheart { get; set; } // narrowing "sweetheart" property's type
}

public interface Wife : Woman // extending Woman interface
{
    new Husband darling { get; set; } // narrowing "darling" property's type
}

public class RandomHusband : Husband // implementing the Husband interface
{
    private RandomWife wife;
    public Wife sweetheart { get { return wife; } set { wife = value; } }
}

public class RandomWife : Wife // implementing the Wife interface
{
    private RandomHusband husband;
    public Husband darling { get { return husband; } set { husband = value; } }
}

This code is wrong, it doesn't work. I'm beeing notified that I didn't implement the basic Man.sweetheart and Woman.darling properties, and that the implemented Husband.sweetheart and Wife.darling will not do, because the types don't match. Is there any way of narrowing a property's type to a derived one? How do you attain it in C#?

like image 799
Paul Roman Avatar asked Nov 22 '12 19:11

Paul Roman


People also ask

Can be inherited by a derived class?

The derived class inherits all members and member functions of a base class. The derived class can have more functionality with respect to the Base class and can easily access the Base class. A Derived class is also called a child class or subclass.

What are derived class can add?

A class can be used as the base class for a derived new class. The derived class inherits all of the properties of the base class. The derived class can add new members or change base class members.

What is derived in C++?

A derived class is a class that is constructed from a base class or an existing class. It has a tendency to acquire all the methods and properties of a base class. It is also known as a subclass or child class.

Can the derived class be made?

Derived class pointer cannot point to base class. [C]. Pointer to derived class cannot be created.


2 Answers

You can do this by parameterising your Man and Woman interfaces with the concrete implementation types:

public interface IMan<M, W>
    where M : IMan<M, W>
    where W : IWoman<W, M>
{
    W Sweetheart { get; set; }
}

 public interface IWoman<W, M>
    where W : IWoman<W, M>
    where M : IMan<M, W>
{
    M Darling { get; set; }
}

Your implementations are then:

public class Man : IMan<Man, Woman>
{
    public Woman Sweetheart { get; set; }
}

public class Woman : IWoman<Woman, Man>
{
    public Man Darling { get; set; }
}

public class Husband : IMan<Husband, Wife>
{
    public Wife Sweetheart { get; set; }
}

public class Wife : IWoman<Wife, Husband>
{
    public Husband Darling { get; set; }
}

Since the types get quite complicated, you might want to consider moving the relationship into an external class/interface:

public interface Relationship<TMan, TWoman> 
    where TMan : Man 
    where TWoman : Woman
{
    TMan Darling { get; }
    TWoman Sweetheart { get; }
}

public class Marriage : Relationship<Husband, Wife>
{
}

Then you can use this class to retain type safety when dealing with concrete implementations:

public static void HandleMarriage(Relationship<Husband, Wife> marriage)
{
    Husband h = marriage.Darling;
    Wife w = marriage.Sweetheart;
}
like image 64
Lee Avatar answered Oct 07 '22 08:10

Lee


you will still need to satisy the Man and Woman interfaces as well as the Husband and Wife...

public class RandomWife : Wife // implementing the Wife interface

    {
        private RandomHusband husband;
        public Husband darling { get { return husband; } set { husband = value; } }
        public Man  Wife.darling { get { return husband; } set { /* can't set anything */ } }

    }
like image 26
Keith Nicholas Avatar answered Oct 07 '22 07:10

Keith Nicholas