Utilizzare la reflection per chiamare metodo generico su istanza di oggetto con la firma: SomeObject.SomeGenericInstanceMethod (argomento T)
-
12-10-2019 - |
Domanda
Come faccio a chiamare SomeObject.SomeGenericInstanceMethod<T>(T arg)
?
Ci sono un paio di post su chiamare i metodi generici, ma non abbastanza come questo. Il problema è che il parametro del metodo argomento è vincolato al parametro generico.
So che se la firma fosse invece
SomeObject.SomeGenericInstanceMethod<T>(string arg)
quindi ho potuto ottenere il MethodInfo con
typeof (SomeObject).GetMethod("SomeGenericInstanceMethod", new Type[]{typeof (string)}).MakeGenericMethod(typeof(GenericParameter))
Quindi, come posso fare su come ottenere il MethodInfo quando gli argomenti regolari sono di un tipo generico? Grazie!
Inoltre, non ci può essere o non essere di tipo vincoli sul parametro generico.
Soluzione
Lo fate esattamente nello stesso modo.
Quando si chiama MethodInfo.Invoke, si passa tutti gli argomenti in un object[]
comunque, quindi non è come si deve conoscere i tipi in fase di compilazione.
Esempio:
using System;
using System.Reflection;
class Test
{
public static void Foo<T>(T item)
{
Console.WriteLine("{0}: {1}", typeof(T), item);
}
static void CallByReflection(string name, Type typeArg,
object value)
{
// Just for simplicity, assume it's public etc
MethodInfo method = typeof(Test).GetMethod(name);
MethodInfo generic = method.MakeGenericMethod(typeArg);
generic.Invoke(null, new object[] { value });
}
static void Main()
{
CallByReflection("Foo", typeof(object), "actually a string");
CallByReflection("Foo", typeof(string), "still a string");
// This would throw an exception
// CallByReflection("Foo", typeof(int), "oops");
}
}
Altri suggerimenti
Lo fate esattamente nello stesso modo, ma passare un'istanza del vostro oggetto:
typeof (SomeObject).GetMethod(
"SomeGenericInstanceMethod",
yourObject.GetType())
// Or typeof(TheClass),
// or typeof(T) if you're in a generic method
.MakeGenericMethod(typeof(GenericParameter))
Il metodo MakeGenericMethod si richiede solo per specificare i parametri di tipo generico, non gli argomenti del metodo.
È piacerebbe passare gli argomenti a più tardi, quando si chiama il metodo. Tuttavia, a questo punto, che stanno passando come object
, in modo che non importa di nuovo.