2012-11-22 2 views
13

私は同じプロパティを使用するインターフェイス継承システムを作成しようとしていますが、それは常に派生型です。したがって、基底プロパティは、引き出しインタフェースによって何らかの形でオーバーライドまたは隠される必要があります。派生C#インターフェイスプロパティは、同じ名前のベースインターフェイスプロパティをオーバーライドできますか?

例えば、夫と妻に由来する2つのインタフェースManと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.sweetheartWife.darlingは実装されないことを通知しています。プロパティの型を派生型に絞り込む方法はありますか?あなたはC#でそれをどのように達成していますか?

それでも男と女のインターフェイスだけでなく、夫と妻をsatisyする必要があります
+0

おもしろい質問:) – nawfal

答えて

2

...

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

結局のところ、私はそれをあなたのやり方で行いました。アイデアをありがとう、キース。私が尋ねたやり方に最も近いのは実際にLeeの答えでしたが、実際のコードでは、私は提示したよりももっと複雑な状況でした。そして、あなたの方法のシンプルさはそれだけであることが判明しました。 –

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; 
} 
関連する問題