2010-03-02 7 views
10

In primo luogo, un esempio di qualcosa che funziona come previsto: (tutto il codice è stato eseguito in VS2008 finestra immediata)Perché il tipo di questo oggetto non mostra interfacce tramite riflessione, nonostante ne implementino almeno due?

25 is IComparable 
>> true 

25.GetType().GetInterfaces() 
>> {System.Type[5]} 
>> [0]: {Name = "IComparable" FullName = ... 
>> [1]: {Name = "IFormattable" FullName = ... 
>> ... 

Fin qui tutto bene. Ora proviamo su un oggetto in cui l'interfaccia è ereditata attraverso un tipo di base:

class TestBase : IComparable 
{ 
    public int CompareTo(object obj) { throw new NotImplementedException(); } 
} 

class TheTest : TestBase { } 

Nella finestra immediata:

(new TheTest()) is IComparable 
>> true 

(new TheTest()).GetType().GetInterfaces() 
>> {System.Type[1]} 
>> [0]: {Name = "IComparable" FullName = "System.IComparable"} 

Nessuna sorpresa neanche qui. Come mai il seguente codice non mostra alcuna interfaccia poi:

wcfChannel = ChannelFactory<IMyServiceApi>.CreateChannel(binding, endpointAddress); 

wcfChannel is IMyServiceApi && wcfChannel is ICommunicationObject 
>> true 

typeof(IMyServiceApi).IsInterface && typeof(ICommunicationObject).IsInterface 
>> true 

wcfChannel.GetType().GetInterfaces() 
>> {System.Type[0]} 

Come può tutto quanto sopra è vero allo stesso tempo?

(modificare: aggiunto wcfChannel is ICommunicationObject sopra, che è in questo momento non spiegata dalla risposta che spiega come wcfChannel is IMyServiceApi è vero.)

+0

presumibilmente un effetto collaterale del fatto che questo tipo viene generato in fase di runtime; per curiosità, è un ContextBoundObject? –

+0

Ulteriori informazioni: Visual Studio lo mostra come 'System.Runtime.Remoting.Proxies .__ TransparentProxy'. Impossibile visualizzare ContextBoundObject ovunque. –

risposta

10

E 'perché il tipo di wcfChannel è l'interfaccia stessa:

>> channel.GetType().FullName 
"MyService.IMyServiceApi" 

>> channel.GetType().IsInterface 
true 

>> channel.GetType() == typeof(IMyServiceApi) 
true 

.GetInterfaces() restituisce solo le interfacce ereditate o implementate, ma non l'interfaccia stessa.

In effetti, è insolito che un'istanza di un oggetto sia effettivamente di un tipo di interfaccia, ma come indicato nel commento sulla domanda, l'oggetto è in realtà un proxy trasparente. È logico che quel proxy sia agnostico dell'attuale implementazione dell'interfaccia e si preoccupi solo dell'interfaccia. Il fatto che .GetType() restituisca l'interfaccia rende il proxy più trasparente possibile.

+1

Eccellente scoperta! –

+0

Grazie! ------- – Timwi

+0

Sfida numero due: com'è possibile quindi che 'channel is ICommunicationObject' sia anche' true'? :) Ora mi rendo conto che tutto questo è dovuto al fatto che "channel" è un oggetto .NET Remoting, ma Reflection espone il fatto che 'channel' implementa' ICommunicationObject' in qualche modo? –

Problemi correlati