16

我正在尝试创建一个接口继承系统,该系统使用相同的属性但始终具有进一步的派生类型。所以基属性应该被派生接口以某种方式覆盖或隐藏。

例如,派生为丈夫和妻子的两个界面,男人和女人,也是界面。Man 和 Husband 接口都有一个“sweetheart”属性,而 Woman 和 Wife 有一个“darling”属性。现在,Man 的“sweetheart”属性是 Woman 类型,而 Husband 的相同“sweetheart”属性应该是 Wife(源自 Woman)。女人和妻子的“宠儿”财产也是如此。

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; } }
}

这段代码是错误的,它不起作用。我收到通知说我没有实现基本Man.sweetheartWoman.darling属性,并且已实现Husband.sweetheart并且Wife.darling不会做,因为类型不匹配。有没有办法将属性的类型缩小到派生的类型?你如何在 C# 中实现它?

4

2 回答 2

16

您可以通过使用具体实现类型参数化您的Man和接口来做到这一点:Woman

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; }
}

您的实现是:

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; }
}

由于类型变得相当复杂,您可能需要考虑将关系移动到外部类/接口中:

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

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

然后你可以在处理具体实现时使用这个类来保持类型安全:

public static void HandleMarriage(Relationship<Husband, Wife> marriage)
{
    Husband h = marriage.Darling;
    Wife w = marriage.Sweetheart;
}
于 2012-11-22T20:13:40.497 回答
3

你仍然需要满足男人和女人的界面以及丈夫和妻子......

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 */ } }

    }
于 2012-11-22T19:55:50.940 回答