我有一个asp.net网页。这是实现页面的类:
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();
}
}我正试图动态地连接一个事件处理程序。由于某些原因,method仍然是空的,我不知道为什么。我以前已经做过很多次了,我不知道我错过了什么。
编辑:我发现this.GetType()返回页面ASP.default_aspx的类型,而不是实现页面的实际类型。我真不知道怎么才能避开这一切..。
发布于 2014-12-27 23:34:43
为了其他人的利益,如果您传递的参数与要查找的方法的参数不匹配,GetMethod()也可以返回null。因此,例如,如果您试图找到该方法:
SomeMethod(int intParam, string stringParam)您需要将参数类型传递给GetMethod
type.GetMethod("SomeMethod", new[] { typeof(int), typeof(string) });或者,如果要指定特殊绑定标志:
type.GetMethod("SomeMethod", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(int), typeof(string) }, null);发布于 2013-09-02 10:52:00
有两件事需要注意。
当您使用:(1):
this.GetType()或者仅仅是GetType(),返回的类型是实际实例的实际运行时类型。由于_Default是一个非密封类,该类型很可能是一个比_Default更派生的(更专门的类型),也就是说,某些类将_Default作为其直接或间接基类。
如果您想要的始终是“常量”类型_Default,请使用typeof关键字,所以请使用:
typeof(_Default)而不是GetType()。光靠这个就能解决你的问题。
(2) --即使指定了BindingFlags.NonPublic,也不会返回继承的private成员。通过选择绑定标志,将返回在同一个类(派生类)中声明的private方法,但不返回从基类继承的private方法。但是,对于internal和protected成员,将返回类本身声明的成员和基类中声明的成员。
这可能有些道理,因为private方法并不意味着要从派生类调用。
将DynamicHandler方法的访问级别从private更改为protected (如另一个答案中的建议)就足以解决您的问题,因为在使用BindingFlags.NonPublic时会选择继承的受保护成员。
有趣的是,您无法使用private获得继承的BindingFlags成员。相关线程C#: Accessing Inherited Private Instance Members Through Reflection。当然,可以编写一个搜索所有基类型的方法,例如:
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;
}光是这样也能解决你的问题。
https://stackoverflow.com/questions/18569001
复制相似问题