2012-11-22 82 views
13

我想創建一個接口繼承系統,使用相同的屬性,但始終是一個進一步的派生類型。所以基本屬性應該以某種方式覆蓋或隱藏在派生接口中。可以派生的C#接口屬性覆蓋具有相同名稱的基礎接口屬性嗎?

舉個例子,兩個接口,男人和女人,衍生成丈夫和妻子,也接口。男人和丈夫的界面都有一個「甜心」財產,而女人和妻子有一個「親愛的」財產。現在,男人的「甜心」財產屬於女人類型,而丈夫同樣的「甜心」財產應該是妻子(源自女人)。和女人和妻子的「親愛的」財產一樣。

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.sweetheartWife.darling不會這樣做,因爲類型不匹配。是否有任何方法將屬性類型縮小爲派生類型?你如何在C#中實現它?

+0

有趣的問題:) – nawfal

回答

2

你仍然需要satisy,男人和女人的接口,以及丈夫和妻子...

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

    } 
+0

你不能在沒有劇組的情況下在你的顯式實現中設置丈夫,並且不能保證它是一個RandomHusband實例。如果集合;可以從IWife/IHusband中刪除,這將是理想的。 – drch

+0

非常好的點... –

+0

畢竟,我做到了你的方式,並沒有問題。感謝這個想法,Keith。實際上,李的回答與我問的方式最接近,就像我問的那樣,但在實際的代碼中,我的情況比我提出的要多。事實證明,你的方法簡單就是這樣。 –

13

您可以通過具體的實現類型參數化的ManWoman接口做到這一點:

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