2015-09-14 17 views
6

Powiedzmy istnieje klasa A ze bez parametrów metody instancjiWywołanie metody instancji statycznie

class A 
{ 
    public A(int x) { this.x = x; } 
    private int x; 
    public int foo() { return x; } 
} 

Łatwo wywołać metodę przy użyciu odbicia:

A a = new A(100); 
var method = typeof(A).GetMethod("foo"); 
var result = method.Invoke(a, new object[0]); // 100 

Jednakże chcę, aby wywołać metodę tak jakby był statyczny

var staticmethod = Something(typeof(A), "foo"); 
var result = staticmethod.Invoke(null, new object[] { a }); 

Czy jest jakiś sposób mogę uzyskać to staticmethod?

UWAGA: Chcę Something być uniwersalny, tzn A może być dowolna klasa, a foo może być dowolna metoda instancji.

EDIT: Żeby było jasne:

Nie ma statyczna metoda w klasie A.

Istnieje metoda instancji bez parametrów o nazwie foo.

Chcę wywołać (używając MethodInfo.Invoke) foo AS JEŻELI jest to metoda statyczna, jako parametr przyjmuje klasę A.

EDIT2: Dlaczego chcę to: (aby pomóc lepiej zrozumieć)

Mam listę metod statycznych, które wykonuje podobną pracę dla różnych typów i są przechowywane w słowniku Dictionary<Type, MethodInfo> dict.

Tak więc, ilekroć mam obiektu obj i chcą, aby wykonać zadanie, mogę

dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... }); 

Teraz chcę dodać metody instancji do niego, jak również, ale będzie to wymagać mnie do zapamiętania, które metody są statyczne i które metody są instancjami wiążącymi i wywołują je na różne sposoby:

dict[obj.GetType()].Invoke(null, new object[] { obj, param1, param2, ... }); // static methods 
dict[obj.GetType()].Invoke(obj, new object[] { param1, param2, ... }); // instance methods 

Co jest niewygodne. Więc chcę uzyskać statyczny MethodInfo z metod instancji, przed dodaniem ich do dyktowania.

EDIT3: Nie rozumiem, dlaczego to pytanie jest oznaczone jako duplikat. Połączona strona NIE odpowiada na moje pytanie. Jeśli czegoś brakuje, proszę powiedz mi.

prowadzi link strona ma kilka odpowiedzi, ale oni albo

  1. wymaga, że ​​wiem, jak wiele argumentów foo bierze lub
  2. daje metodę, która zajmuje object[] jako parametru, zamiast listy parametrów .

Tak więc żadna z nich nie pasuje tutaj.

Po kilku badań odkryłem, że istnieje coś blisko tego, co trzeba:

A a = new A(100); 
var method = typeof(A).GetMethod("foo"); 
var deleg = Delegate.CreateDelegate(typeof(Func<A, int>), method) 
var result = deleg.DynamicInvoke(new object[] { a }); // 100 

Tutaj trwa new object[] { a } jako argumentu. Ale chodzi o to, skoro nie wiem, jak wygląda foo, jak mogę przekazać pierwszy argument z Delegate.CreateDelegate?

Ostatnia edycja: Znaleziono rozwiązanie samodzielnie. Dziękuję za pomoc!

+0

Możesz wywołać metody statyczne za pomocą pierwszej metody. W przypadku metody statycznej pierwszy parametr "Invoke" jest ignorowany. – Donnie

+0

@Donnie Nie sądzę, że chce wywołać metodę statyczną. Próbuje wywołać metodę instancji, taką jak metoda statyczna. –

+0

@Donnie Nie chcę wywoływać metody statycznej, chcę wywołać metodę instancji za pomocą drugiego podejścia –

Odpowiedz

0

metody statyczne i metody instancji może być ujednolicone poprzez stworzenie delegata, a następnie wywołanie DynamicInvoke:

Dictionary<Type, Delegate> dict = new Dictionary<Type, Delegate>(); 

void AddMethod(Type type, String methodName) 
{ 
    var method = type.GetMethod(methodName); 
    var types = method.GetParameters().ConvertAll(p => p.ParameterType).ToList(); 
    if (!method.IsStatic) 
     types.Insert(0, type); 
    types.Add(method.ReturnType); 
    var delegType = Expression.GetFuncType(types.ToArray()); 
    var deleg = method.CreateDelegate(delegType); 
    dict.Add(type, deleg); 
} 

object GetJobResult(object obj, params object[] additionalParams) 
{ 
    var paramList = additionalParams.ToList(); 
    paramList.Insert(0, obj); 
    return dict[obj.GetType()].DynamicInvoke(paramList.ToArray()); 
} 
5

ale będzie to wymagać mnie do zapamiętania, które metody są statyczne, a które metody są instancji wiązanie i wywołać je w różny sposób

Nie ma potrzeby, aby go zapamiętać, ponieważ metoda zna ten sam:

MethodInfo mi = GetTheMethodFromSomewhere(); 
object[] args = new object[] { obj, param1, param2, … }; 
if (mi.IsStatic) 
    mi.Invoke(null, args); 
else 
    mi.Invoke(args[0], args.Skip(1).ToArray()); 
+0

To jest dokładnie to, czego nie chcę ... JEŚLI wywołujesz je na różne sposoby –

+1

Cóż, nie możesz * zrobić tego bez wywoływania ich inaczej. Oni * mogą * być inwokowani inaczej, ponieważ są zasadniczo różni. W każdy inny sposób, jaki wymyślisz (np. 'DynamicInvoke'), będzie w pewien sposób enkapsulować różne wywołania. – poke

+0

Cóż, nie mówię tu o podstawowym mechanizmie wywoływania metod, ale o tym, jak wywołać metodę według kodu - i moja odpowiedź wygląda dobrze. Przy okazji, naprawdę wątpię, że podstawowy mechanizm jest inny, jest tylko domyślnym "tym" pierwszym parametrem. –