2012-11-22 4 views
13

Ich versuche, ein Schnittstellenvererberungssystem zu erstellen, das dieselbe Eigenschaft aber immer von einem weiteren abgeleiteten Typ verwendet. Daher sollte die Basiseigenschaft durch die ableitende Schnittstelle irgendwie überschrieben oder verborgen werden.Können abgeleitete C# -Schnittstelleneigenschaften die Eigenschaften der Basisschnittstelle mit demselben Namen überschreiben?

Nehmen Sie zum Beispiel zwei Schnittstellen, Mann und Frau, die in Mann und Frau, auch Schnittstellen ableiten. Mann und Ehemann Schnittstellen haben beide eine "Schatz" Eigenschaft, während Frau und Frau eine "Liebling" Eigenschaft haben. Nun ist die "Schatz" -Eigenschaft des Mannes vom Typ Frau, während die "Schatz" -Eigenschaft des Ehemanns eine Frau (abgeleitet von Frau) sein sollte. Und das Gleiche mit dem "Liebling" der Frau und der Frau.

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

Dieser Code ist falsch, es funktioniert nicht. Ich werde benachrichtigt, dass ich die grundlegenden Eigenschaften Man.sweetheart und Woman.darling nicht implementiert habe und dass die implementierten Husband.sweetheart und Wife.darling nicht tun, weil die Typen nicht übereinstimmen. Gibt es eine Möglichkeit, den Typ einer Eigenschaft auf einen abgeleiteten zu beschränken? Wie erreichst du es in C#?

+0

interessante Frage :) – nawfal

Antwort

2

Sie noch den Mann und Frau Schnittstellen sowie den Mann und Frau müssen ...

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

Sie können Ehemann in Ihrer expliziten Implementierung ohne eine Besetzung festlegen, und es gibt keine Garantie, dass es eine RandomHusband-Instanz wird. Wenn der Satz; kann aus IWife/IHusband entfernt werden, das wäre ideal. – drch

+0

sehr guter Punkt ... –

+0

Immerhin habe ich es auf Ihre Weise gemacht, und es ist in Ordnung. Danke für die Idee, Keith. Es war tatsächlich Lees Antwort, die meiner Anfrage am nächsten kam, so wie ich sie gestellt hatte, aber in dem richtigen Code hatte ich eine komlexere Situation als ich präsentierte. Und es stellte sich heraus, dass die Einfachheit Ihrer Methode genau das war. –

13

Sie können dies tun, um satisy von Ihren Man und Woman Schnittstellen mit den konkreten Umsetzungstypen Parametrisierung:

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

Ihre Implementierungen sind dann:

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

Da die Typen ziemlich kompliziert, vielleicht wollen betrachten Sie die Beziehung in eine externe Klasse/Schnittstelle zu bewegen:

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

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

Dann können Sie diese Klasse verwenden, um Typsicherheit beibehalten, wenn sie mit konkreten Implementierungen zu tun:

public static void HandleMarriage(Relationship<Husband, Wife> marriage) 
{ 
    Husband h = marriage.Darling; 
    Wife w = marriage.Sweetheart; 
} 
Verwandte Themen