2015-09-14 2 views
6

Допустим есть класс A с без параметров метода экземпляраInvoke метод экземпляра статически

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

Это легко вызвать метод с помощью отражения:

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

Однако, я хочу, чтобы вызвать метод как если бы он был статичным

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

Есть ли способ получить это staticmethod?

Примечание: Я хочу Something быть универсальными, то есть A может быть любым классом, и foo может быть любым методом экземпляра.

EDIT: Чтобы сделать вещи ясно:

Там нет статического метода в классе A.

Существует метод без параметров, который называется foo.

Я хочу вызвать (используя MethodInfo.Invoke) foo AS ЕСЛИ это статический метод, который принимает в качестве параметра класс A.

EDIT2: Почему я хочу это: (чтобы помочь вам лучше понять)

У меня есть список статических методов, что делает подобную работу для различных типов, и они хранятся в словаре Dictionary<Type, MethodInfo> dict.

Таким образом, всякий раз, когда у меня есть объект obj и хочу, чтобы сделать эту работу, я могу

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

Теперь я хочу, чтобы добавить методы экземпляра в нее, а также, но это потребует, чтобы я помню, какие методы статические и какие методы экземпляра связи и вызывать их по-разному:

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

что неудобно. Поэтому я хочу получить статические методы MethodInfo из методов экземпляра, прежде чем добавлять их в dict.

EDIT3: Я не понимаю, почему этот вопрос отмечен как дубликат. Связанная страница НЕ отвечает на мой вопрос. Если мне что-то не хватает, скажите, пожалуйста.

Связанная страница имеет несколько ответов, но они либо

  1. требует, чтобы я знал, как много аргументов foo принимает или
  2. дает метод, который принимает object[] в качестве параметра, вместо списка параметров ,

Поэтому ни один из них не подходит здесь.

После некоторых исследований я обнаружил, что есть что-то близкое к тому, что мне нужно:

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 

Здесь он принимает new object[] { a } в качестве аргумента. Но дело в том, что, поскольку я не знаю, как выглядит foo, как я могу передать первый аргумент Delegate.CreateDelegate?

Последний EDIT: Нашел решение самостоятельно. Спасибо вам за помощь!

+0

Вы можете вызвать статические методы с помощью первого метода. В случае статического метода первый параметр 'Invoke' игнорируется. – Donnie

+0

@ Donnie Я не думаю, что он хочет вызвать статический метод. Он пытается вызвать метод экземпляра, как статический метод. –

+0

@Donnie Я не хочу вызывать статический метод, я хочу вызвать метод экземпляра, используя второй подход –

ответ

0

Статические методы и методы экземпляра могут быть объединены путем создания делегата, а затем вызвать 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

но это потребует, чтобы я помню, какие методы являются статическими и какие методы экземпляра связи и вызывать их по-разному

Нет необходимости помнить об этом, потому что метод знает это сам:

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

Это именно то, чего я не хочу ... Вы обратились к ним по-разному –

+1

Ну, вы * не можете * сделать это, не называя их по-разному. Они * имеют * для вызова иначе, потому что они принципиально разные. Каждый другой способ, с которым вы столкнетесь (например, «DynamicInvoke»), каким-то образом инкапсулирует и другую инфокацию. – poke

+0

Ну, я не говорю о базовом механизме вызова методов, но как вызвать метод с помощью кода - и мой ответ выглядит просто замечательно. Кстати, я действительно сомневаюсь, что основной механизм отличается, это просто неявный «этот» первый параметр –

Смежные вопросы