我在运行时使用Reflection做一些类型分析。如果我有一个MethodInfo示例,我如何判断这是一个“真实的的”方法还是一个属性的getter/setter方法?如果它是一个属性,我如何找到它的宿主PropertyInfo?
2o7dmzc51#
好吧,getter和setter后面的方法是“真实的的”方法。重新跟踪到属性-模式(return vs take 1 arg)将有助于缩小范围-但您必须在每个属性上调用GetGetMethod/GetSetMethod来查找属性。你可以大概试试Name(少了get__/set__)--但是感觉很脆弱,下面是更长的版本(没有使用Name):
Name
static PropertyInfo GetProperty(MethodInfo method) { bool takesArg = method.GetParameters().Length == 1; bool hasReturn = method.ReturnType != typeof(void); if (takesArg == hasReturn) return null; if (takesArg) { return method.DeclaringType.GetProperties() .Where(prop => prop.GetSetMethod() == method).FirstOrDefault(); } else { return method.DeclaringType.GetProperties() .Where(prop => prop.GetGetMethod() == method).FirstOrDefault(); } }
3pmvbmvn2#
Ecma 335指定(但不要求)编译器使用get_/set_前缀(第22.28章),我不知道有什么语言违反了这个建议。
public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) { if (!method.IsSpecialName) return null; return t.GetProperty(method.Name.Substring(4), BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); }
djmepvbi3#
研究一下MethodBase.IsSpecialName,那些不应该明显可见的方法,比如属性访问器,事件订阅方法和运算符重载都使用这个标志。据我所知,如果不迭代属性并比较方法,就无法找到PropertyInfo。
MethodBase.IsSpecialName
PropertyInfo
5t7ly7z54#
我真的很想把这个作为一个评论,但我不能,因为我的代表是不够高:Marc Gravell的代码中存在一个错误:如果它是一个索引器,它将返回null,即使父属性存在。有这样的快速失败是很好的,但我认为我们只能在它既没有返回值也没有参数的情况下这样做:
[Pure] public static PropertyInfo GetParentProperty(this MethodInfo method) { if (method == null) throw new ArgumentNullException("method"); var takesArg = method.GetParameters().Length == 1; var hasReturn = method.ReturnType != typeof(void); if (!(takesArg || hasReturn)) return null; if (takesArg && !hasReturn) { return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method); } else { return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method); } }
bksxznpy5#
对于今天的.NET,我相信下面的答案与Marc的答案相同,但更简洁,可能更有效。
public static PropertyInfo? GetPropertyInfo(this MethodInfo getSetMethodInfo) => getSetMethodInfo.DeclaringType?.GetProperties() .FirstOrDefault(prop => prop.GetSetMethod() == getSetMethodInfo || prop.GetGetMethod() == getSetMethodInfo);
4xy9mtcn6#
要使用的技巧是BindingFlags.DeclaredOnly和IsSpecialName
6条答案
按热度按时间2o7dmzc51#
好吧,getter和setter后面的方法是“真实的的”方法。
重新跟踪到属性-模式(return vs take 1 arg)将有助于缩小范围-但您必须在每个属性上调用GetGetMethod/GetSetMethod来查找属性。
你可以大概试试
Name
(少了get__/set__)--但是感觉很脆弱,下面是更长的版本(没有使用Name
):3pmvbmvn2#
Ecma 335指定(但不要求)编译器使用get_/set_前缀(第22.28章),我不知道有什么语言违反了这个建议。
djmepvbi3#
研究一下
MethodBase.IsSpecialName
,那些不应该明显可见的方法,比如属性访问器,事件订阅方法和运算符重载都使用这个标志。据我所知,如果不迭代属性并比较方法,就无法找到
PropertyInfo
。5t7ly7z54#
我真的很想把这个作为一个评论,但我不能,因为我的代表是不够高:
Marc Gravell的代码中存在一个错误:如果它是一个索引器,它将返回null,即使父属性存在。有这样的快速失败是很好的,但我认为我们只能在它既没有返回值也没有参数的情况下这样做:
bksxznpy5#
对于今天的.NET,我相信下面的答案与Marc的答案相同,但更简洁,可能更有效。
4xy9mtcn6#
要使用的技巧是BindingFlags.DeclaredOnly和IsSpecialName