2012-11-22 12 views
13

Sto provando a creare un sistema di ereditarietà dell'interfaccia che utilizza la stessa proprietà ma sempre di un altro tipo derivato. Quindi la proprietà di base dovrebbe essere in qualche modo sovrascritta o nascosta dall'interfaccia derivante.Le proprietà dell'interfaccia C# derivate possono sovrascrivere le proprietà dell'interfaccia di base con lo stesso nome?

Prendere, ad esempio, due interfacce, Uomo e Donna, che derivano in Marito e Moglie, anche interfacce. Le interfacce uomo e marito hanno entrambe una proprietà "dolce", mentre la donna e la moglie hanno una proprietà "cara". Ora, la proprietà "tesoro" dell'uomo è di tipo Donna, mentre la stessa proprietà "tesoro" del marito dovrebbe essere una moglie (derivata dalla donna). E lo stesso con la proprietà "cara" della donna e della moglie.

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

Questo codice è errato, non funziona. Sono stato informato che non ho implementato le proprietà di base Man.sweetheart e Woman.darling e che l'implementazione Husband.sweetheart e Wife.darling non verrà eseguita, poiché i tipi non corrispondono. Esiste un modo per restringere il tipo di una proprietà a una derivata? Come si ottiene in C#?

+0

domanda interessante :) – nawfal

risposta

2

sarà ancora bisogno di satisy le interfacce uomo e donna così come il marito e moglie ...

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

Non puoi impostare il marito nella tua implementazione esplicita senza cast e non c'è alcuna garanzia che sia un'istanza RandomHusband. Se il set; può essere rimosso da IWife/IHusband, questo sarebbe l'ideale. – drch

+0

ottimo punto ... –

+0

Dopo tutto, ho fatto a modo tuo, e va bene. Grazie per l'idea, Keith. In realtà era la risposta di Lee il più vicino a quello che chiedevo, nel modo in cui lo chiedevo, ma nel codice reale, avevo una situazione più complessa di quella che presentavo. E si è scoperto che la semplicità del tuo metodo era proprio questo. –

13

È possibile effettuare questa operazione parametrizzazione tuoi Man e Woman interfacce con i tipi di implementazione concreti:

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

implementazioni sono quindi:

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

Poiché i tipi ottenere abbastanza complicato, si potrebbe prendere in considerazione di spostare il rapporto in una classe/interfaccia esterna:

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

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

quindi è possibile utilizzare questa classe per mantenere la sicurezza di tipo quando si tratta di implementazioni concrete:

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