2010-12-31 10 views
5

Sto utilizzando reflection per chiamare un metodo generico con un tipo determinato in fase di esecuzione. Il mio codice è il seguente:Chiama Metodo generico che utilizza il tipo di runtime e l'oggetto restituisci cast

Type tType = Type.GetType(pLoadOut.Type); 
MethodInfo method = typeof(ApiSerialiseHelper).GetMethod("Deserialise", new Type[] { typeof(string) }); 
MethodInfo generic = method.MakeGenericMethod(tType); 
generic.Invoke(obj, new object[] { pLoadOut.Data }); 

Funziona bene. Tuttavia il metodo generic.Invoke restituisce un oggetto, ma quello che vorrei è il tipo determinato in fase di esecuzione. Questo è possibile con questo approccio, o c'è un'opzione migliore?

Mark

+0

Cosa intendi con "ma quello che vorrei è il tipo determinato in fase di esecuzione"? – decyclone

+0

Supponendo che tType abbia un metodo chiamato DoSomething(). Mi piacerebbe poterlo fare; var a = generic.Invoke (obj, new object [] {pLoadOut.Data}); a.DoSomething(); – markpirvine

+0

Qual è il tipo di ritorno statico effettivo di 'Deserialize'? La varianza del delegato potrebbe esserti utile. –

risposta

5

Il tipo IS determinato in fase di esecuzione. È il tipo della variabile di riferimento che è oggetto, l'istanza effettiva è fortemente tipizzata.

Questo è il meglio che si può fare, considerando che si sta utilizzando la riflessione per ottenere in modo dinamico l'accesso a un metodo per il quale il compilatore non ha informazioni sul tipo - potrebbe non esistere nemmeno nell'ambiente di costruzione.

MODIFICA: Se si conosce qualcosa sul tipo restituito da Deserialize, è possibile usufruire della varianza dei delegati. Ad esempio:

Type tType = Type.GetType(pLoadOut.Type); 
MethodInfo method = typeof(ApiSerialiseHelper).GetMethod("Deserialise", new Type[] { typeof(string) }); 
MethodInfo generic = method.MakeGenericMethod(tType); 
Converter<string,ISomething> deser = (Converter<string,ISomething>)Delegate.CreateDelegate(typeof(Converter<string,ISomething>),generic); 
ISomething result = deser(pLoadOut.Data); 
0

Se gli oggetti restituiti hanno un antenato o un'interfaccia comune, è possibile eseguire il cast su di essi. Se non lo fanno, allora dovrebbero, ad es. se tutti i tipi di restituzione possibili hanno un metodo denominato DoSomething(), quindi creare un'interfaccia con un metodo DoSomething().

+0

E quell'interfaccia deve essere conosciuta in fase di compilazione, anche se il tipo più derivato non lo è. –

Problemi correlati