2013-03-14 4 views
5

Perché il Type.GetProperty(string) non ottiene una proprietà da un'interfaccia di base se il tipo è un'interfaccia? Ad esempio, il codice seguente stampa:Perché C# Type.GetProperty() si comporta in modo diverso per le interfacce rispetto alle classi base?

System.String X 
null 
System.String X 
System.String X 

che sembra incoerente:

void Main() 
{ 
    Console.WriteLine(typeof(I1).GetProperty("X")); 
    Console.WriteLine(typeof(I2).GetProperty("X")); 
    Console.WriteLine(typeof(C1).GetProperty("X")); 
    Console.WriteLine(typeof(C2).GetProperty("X"));; 
} 

public interface I1 { string X { get; } } 

public interface I2 : I1 { } 

public class C1 { public string X { get { return "x"; } } } 

public class C2 : C1 { } 

EDIT: un altro aspetto del runtime che supporta la risposta di Cole è la seguente:

public class C : I2 { 
    // not allowed: the error is 
    // 'I2.X' in explicit interface declaration is not a member of interface 
    string I2.X { get; set; } 

    // allowed 
    string I1.X { get; set; } 
} 
+0

Non ha nulla a che fare con la classe o l'interfaccia. X è privato in uno e pubblico nell'altro. –

+0

Le interfacce possono essere implementate esplicitamente ('nascondere' i metodi sulla classe di implementazione), mentre le proprietà pubbliche su una classe sono sempre visibili. Vedrete lo stesso comportamento se implementate esplicitamente I1 su C1, mentre se lo implementate implicitamente, GetProperty lo troverà. –

+1

@CoryNelson tutte le proprietà dell'interfaccia sono pubbliche. O stai dicendo che I2 implementa esplicitamente I1 e quindi i suoi metodi I1 sono privati? Se è vero, allora perché puoi accedere a X tramite un'istanza di I2 senza cast? – ChaseMedallion

risposta

6

Ricorda che l'ereditarietà della classe non è la stessa dell'implementazione dell'interfaccia.

Una classe derivata e la sua classe base hanno una relazione -. Se D : B quindi Dè unB. Se B ha una proprietà, quindi D avrà per definizione anche quella stessa proprietà, perché è quello che quella relazione significa; la "sostanza" di D è in qualche modo alterata dalla sua relazione con B.

interfacce forniscono alcuna implementazione, in modo che quando si dice ID : IB, non si stanno realmente dicendo IDè unIB nello stesso modo in cui si fa con le classi. Cosa significherebbe? ID e IB non sono cose; sono accordi. Non c'è niente da cambiare. Invece, stai dicendo "una classe che implementa ID deve anche fornire un'implementazione per IB".

Il fatto che ID derivi da IB non cambi ID perché non ha sostanza da modificare. Significa semplicemente che qualsiasi classe che promette di soddisfare il contratto specificato da ID deve anche essere pronta ad aderire ad un insieme aggiuntivo di requisiti.

Tenendo questo in mente, se IB fornisce una proprietà X, la risposta corretta a "non ID ha una proprietà X?" è no. ID richiede anche di implementare IB, che ha una proprietà X, ma non ha una proprietà X.

+0

Quello che stai dicendo ha senso, ma puoi fondarlo in qualche tipo di documentazione C# o una descrizione di come le classi e le interfacce differiscono sotto il cofano? Puoi segnalare altri comportamenti nell'API di riflessione che sono coerenti con questa distinzione (oltre all'ovvio parallelo di GetMethod). Ad esempio, GetInterfaces() funziona in modo equivalente per classi e interfacce. – ChaseMedallion

+2

@ChaseMedallion: come si nota, la domanda riguarda il comportamento della libreria Reflection. Non è affatto richiesto che le regole di Reflection siano le stesse di C#, o VB o F #, o qualsiasi altra lingua gestita. La specifica C# non ha nulla da dire sull'argomento di cosa dovrebbe fare Reflection; la documentazione che dovresti cercare è la documentazione della libreria Reflection. –

+0

@ChaseMedallion: direi che 'GetProperty()' _also_ funziona in modo equivalente per classi e interfacce. Restituisce proprietà che sono definite sul tipo. In 'ID: IB' con' X' su 'IB', la semantica di implementazione dell'interfaccia significa che' X' non è definito su 'ID'. Per quanto riguarda la documentazione, temo di non saperlo. Sto solo cercando di spiegare il comportamento che stai vedendo in base alla mia comprensione della semantica dell'ereditarietà rispetto a quella dell'implementazione. –