Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke instance method statically

Tags:

c#

reflection

Let's say there is a class A with an parameterless instance method

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

It's easy to invoke the method using reflection:

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

However, I want to invoke the method as if it is static

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

Is there any way I can get this staticmethod?

NOTE: I want Something to be universal, i.e. A can be any class, and foo can be any instance method.

EDIT: To make things clear:

There is no static method in class A.

There is a parameterless instance method called foo.

I want to invoke (using MethodInfo.Invoke) foo AS IF it is a static method, that takes class A as the parameter.

EDIT2: Why I want this: (to help you understand better)

I have a list of static methods that does similar job for different types, and they are stored in a dictionary Dictionary<Type, MethodInfo> dict.

Thus, whenever I have an object obj and want to do the job, I can

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

Now I want to add instance methods into it as well, but it will require me to remember which methods are static and which methods are instance-bond, and invoke them in different ways:

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

Which is inconvenient. So I want to get static MethodInfo from instance methods, before adding them into the dict.

EDIT3: I don't understand why this question is marked duplicate. The linked page does NOT answer my question. If I'm missing something, please tell me.

The linked page has several answers, but they either

  1. requires that I know how many arguments foo takes, or
  2. gives a method that takes object[] as the parameter, instead of a list of parameters.

So none of them fit here.

After some research I found that there's something close to what I need:

 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

Here, it takes new object[] { a } as the argument. But the thing is, since I don't know how foo looks like, how can I pass the first argument of Delegate.CreateDelegate?

Last EDIT: Found a solution myself. Thank you for your help guys!

like image 440
Michael Kim Avatar asked Sep 14 '15 05:09

Michael Kim


People also ask

Can you invoke a static method from an instance method?

A static method cannot access a class's instance variables and instance methods, because a static method can be called even when no objects of the class have been instantiated. For the same reason, the this reference cannot be used in a static method.

How do you call a method statically?

A static method can be called directly from the class, without having to create an instance of the class. A static method can only access static variables; it cannot access instance variables. Since the static method refers to the class, the syntax to call or refer to a static method is: class name. method name.

How are static functions invoked?

Calling Static Function It is invoked by using the class name. For example: Math. sqrt(a); //calling the square root function of the Math class.

What is invoke static?

invokestatic looks at the descriptor given in <method-spec>, and determines how many arguments the method takes (this may be zero). It pops these arguments off the operand stack. Then it searches the list of static methods defined by the class, locating the method methodname with a descriptor descriptor.


1 Answers

but it will require me to remember which methods are static and which methods are instance-bond, and invoke them in different ways

No need to remember it because the method knows this itself:

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());
like image 177
poke Avatar answered Oct 17 '22 23:10

poke