GetMethod returns null

I have an asp.net webpage. This is the class that implements the page:

public partial class _Default : System.Web.UI.Page { private readonly string delegateName = "DynamicHandler"; protected void Page_Load(object sender, EventArgs e) { EventInfo evClick = btnTest.GetType().GetEvent("Click"); Type tDelegate = evClick.EventHandlerType; MethodInfo method = this.GetType().GetMethod("DynamicHandler", BindingFlags.NonPublic | BindingFlags.Instance); Delegate d = Delegate.CreateDelegate(tDelegate, this, method); MethodInfo addHandler = evClick.GetAddMethod(); Object[] addHandlerArgs = { d }; addHandler.Invoke(btnTest, addHandlerArgs); } private void DynamicHandler(object sender, EventArgs e) { throw new NotImplementedException(); } } 

I am trying to connect an event handler dynamically. For some reason, method remains empty, and I can't figure out why. I have done this many times before, and I cannot understand what I am missing.

EDIT: I found that this.GetType() returns the ASP.default_aspx page type and not the actual page implementation type. I really don't know how to get around this ...

+4
source share
3 answers

As you found in your editing, the ASPX page is actually compiled into a class that inherits from _Default (where your code is located). Therefore, you need to make DynamicHandler (at least) protected , not private .

Specify BindingFlags.FlattenHierarchy also:

 this.GetType().GetMethod("DynamicHandler", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); 

Strike>

+4
source

In the interest of anyone else, GetMethod() can also return null if the arguments you pass do not match the arguments of the method you are trying to find. So, for example, if you are trying to find a method:

 SomeMethod(int intParam, string stringParam) 

You need to pass parameter types to GetMethod :

 type.GetMethod("SomeMethod", new[] { typeof(int), typeof(string) }); 

Or, if you want to specify special anchor flags:

 type.GetMethod("SomeMethod", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(int), typeof(string) }, null); 
+6
source

There are two things to know about.

(1) When using:

 this.GetType() 

or equivalently just GetType() , the return type is the actual runtime type of the actual instance. Since _Default is a non-printable class, this type may well be more derived (more specialized type) than _Default , that is, some class that has _Default as its direct or indirect base class.

If you always want the "persistent" type _Default , use the typeof keyword, so use:

 typeof(_Default) 

instead of GetType() . This alone will solve your problem.

(2) Even if you specify BindingFlags.NonPublic , inherited private members will not be returned. With your choice, binding flags return private methods declared in the same class (derived class), but private methods inherited from base classes are not returned. However, with members, internal and protected returned as those declared in the class itself, and those declared in the base classes.

This may make sense, since the private method is not intended to be called from a derived class.

Change the access level of your DynamicHandler method from private to, for example. protected (as suggested in another answer) would be enough to solve your problem, since inherited protected members are selected using BindingFlags.NonPublic .

It is still interesting that you cannot get inherited private members with BindingFlags . Related topic C #: accessing inherited private members of an instance through reflection . You can write a method that looks for all the basic types, of course, for example:

 static MethodInfo GetPrivateMethod(Type type, string name) { MethodInfo retVal; do { retVal = type.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); if (retVal != (object)null) break; type = type.BaseType; } while (type != (object)null); return retVal; } 

That alone would also solve your problem.

+3
source

Source: https://habr.com/ru/post/1500105/


All Articles