也就是说,如果MethodInfo
检查方法是属性的getter或setter,还是事件的adder或remover或firer(?),而不枚举所有{{1},我怎么能这样做?在包含类型中。编译器是否用一些信息标记这些方法,这些信息可以让我知道我的Property/EventInfos
何时是一个?
答案 0 :(得分:0)
这不是一个完整的解决方案,但是在属性类型不是EventHandler的情况下,你可以通过检查它们的参数和返回值,从事件添加/删除方法中告诉属性get / set方法。
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
foreach (var methodInfo in typeof(TestClass).GetMethods())
{
if (!methodInfo.IsSpecialName)
continue;
CheckMethod(methodInfo);
}
// Method get_Name -> Property Get
// Method set_Name -> Property Set
// Method add_NameChanged -> Event Add/Remove
// Method remove_NameChanged -> Event Add/Remove
}
static void CheckMethod(MethodInfo info)
{
var parameter = info.GetParameters().FirstOrDefault();
if (parameter != null)
{
if (parameter.ParameterType.BaseType == typeof(MulticastDelegate))
{
Trace.WriteLine($"Method {info.Name} -> Event Add/Remove");
}
else
{
Trace.WriteLine($"Method {info.Name} -> Property Set");
}
}
else if (info.ReturnType != typeof(void))
{
Trace.WriteLine($"Method {info.Name} -> Property Get");
}
}
}
public class TestClass
{
public string Name
{
get { return _name; }
set
{
if (_name == value)
return;
_name = value;
NameChanged?.Invoke(this, value);
}
}
private string _name;
public event EventHandler<string> NameChanged;
}
答案 1 :(得分:0)
手动声明的方法与编译器生成的方法之间至少有一个区别是SpecialName
对象中存在MethodInfo
属性:
要找出与该方法相关联的属性,您需要检查PropertyInfo
个对象,以查找相应的GetMethod
和SetMethod
属性,这些属性将链接到这些方法。
示例LINQPad程序:
void Main()
{
typeof(Test).GetProperties().Select(property => new { property.MetadataToken, property.Name, getter = property.GetMethod?.MetadataToken, setter = property.SetMethod?.MetadataToken }).Dump();
typeof(Test).GetMethods().Select(method => new { method.MetadataToken, method.Name, IsSpecial = (method.Attributes & MethodAttributes.SpecialName) != 0 }).Dump();
}
public class Test
{
public int Value
{
get;
set;
}
}
输出:
答案 2 :(得分:0)
MethodInfo.IsSpecialName对于属性和事件访问器设置为true,对于运算符重载等一些其他特殊方法也是如此。因此,您可以检查此标志并检查参数类型。以下测试程序将输出事件添加/删除访问器:
public class MyEventClass {
private event EventHandler test;
public event EventHandler TestEven {
add { test += value; }
remove { test -= value; }
}
}
课程{ static void Main(string [] args) {
Type myTestClassType = typeof (MyEventClass);
var methods = myTestClassType.GetMethods();
foreach (var methodInfo in methods)
{
if (methodInfo.IsSpecialName)
{
var parameters = methodInfo.GetParameters();
if (parameters.Count() == 1 && parameters.ElementAt(0).ParameterType == typeof (EventHandler) &&
(methodInfo.Name.Contains("add") || methodInfo.Name.Contains("remove")))
{
Console.WriteLine(methodInfo.Name);
}
}
}
}
}