No :-)
Caso 1:
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo result = (Foo)objFoo;
Non v'è alcun riflesso qui, perché si conosce il tipo Foo
in fase di compilazione.
Caso 2: interfacce. Normalmente il migliore ... Non sai che cosa esattamente MakeFoo
ritorni, ma si sa che è un'interfaccia IFoo
...
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
IFoo result = (IFoo)objFoo;
Caso 3: non si è sicuri MakeFoo
rendimenti Foo
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
if (objFoo is Foo)
{
Foo result = (Foo)objFoo;
}
o, simile
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Foo foo = objFoo as Foo;
if (foo != null)
{
// use foo
}
Caso 4: tipo Foo
è completamente sconosciuto al tuo programma. Non si dispone di una classe Foo
referenziabile ...
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Type typeFoo = objFoo.GetType(); // You should check for null values before!
// and now?
dynamic foo = objFoo;
// because you know that foo can Quack(1, 2, 3)!
string result = foo.Quack(1, 2, 3);
// note that it will explode with a RuntimeBinderException if there is no
// string Quack(int, int, int) method!
il dynamic
usa internamente riflessione. Si potrebbe utilizzare la reflection direttamente per ottenere il metodo Quack
e chiamarlo
Caso 5: come caso 4, ma utilizzando direttamente riflessione:
object objFoo = MakeFoo(); // object MakeFoo(){return new Foo();}
Type typeFoo = objFoo.GetType(); // You should check for null values before!
MethodInfo mi = type.GetMethod("Quack"); // You should check if the Quack method
// exists
string result = (string)mi.Invoke(objFoo, new object[] { 1, 2, 3 });
o, con alcuni controlli di integrità, se non si è assicurarsi foo
può Quack
correttamente:
MethodInfo mi = type.GetMethod("Quack",
BindingFlags.Instance | BindingFlags.Public,
null,
new[] { typeof(int), typeof(int), typeof(int) },
null);
if (mi != null && typeof(string).IsAssignableFrom(mi.ReturnType))
{
string result = (string)mi.Invoke(objFoo, new object[] { 1, 2, 3 });
}
caso -Infinity: tipo Foo
è completamente sconosciuto a voi programma. Non hai una classe Foo
referenziabile. Non hai un'interfaccia IFoo
. Non sai nemmeno cosa sia uno , sai solo che è una classe (o forse è una scatola struct
, ma non cambia dal tuo punto di vista ... Non può essere una interface
perché nella alla fine deve esserci sempre un class
/struct
concreto dietro ogni interface
). Non conosci i suoi metodi, i suoi campi, le sue proprietà (perché non sai cosa sia Foo
).
Anche se è possibile trasmettere un valore object
a questa classe sconosciuta, cosa si può fare?Non si può avere metodi nel codice che accettano come valore del parametro/ritorno, perché se da qualche parte si ha:
int INeedFoo(Foo par) { return 0; }
allora è chiaro che si dovrebbe sapere di Foo
. La libreria .NET non può avere metodi che lo accettano come parametro/valore di ritorno, perché se lo fosse, si saprebbe di Foo
.
L'unica cosa che si può fare è passare ad alcuni altri metodi che si scoprono attraverso la riflessione che accettano Foo
come parametro ... Ma il metodo Invoke
accetta un array di object
come parametri ... Non è necessario per trasmettere il tuo object
per chiamare Invoke
! Hai solo bisogno di metterlo nella matrice.
Puoi spiegare cosa stai cercando di fare, dopo "risultato Foo"? –
Nel codice originale è qualcosa come MethodInfo methodInfo = ... typeFoo = methodInfo.ReturnType; Quindi non so quale tipo sarà. – user2341923
Se non sai di che tipo sarà, come si dichiara la variabile sul lato sinistro? –