我得到了:
一个类“T
”,它实现了用我感兴趣的属性修饰的属性。
PropertyInfo
“p
”表示属于(1)I
实现的接口“T
”的属性,(2)基类“B
”T
继承自,或(3)类T
本身。
我需要在T中定义(或继承)属性的属性,即使p
的DeclaringType是T
实现的接口或类T
继承自。因此,我需要一种方法从p
转到PropertyInfo
上实际存在的T
。因此似乎有3种情况:
p.DeclaringType == typeof(T)
这是一个微不足道的案例。我可以遍历T
的属性,直到找到匹配项。例如:
return typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(property => property == p)
p.DeclaringType == typeof(I)
其中I
是T
实现的接口这更复杂。我发现我可以使用InterfaceMapping在p
中查找T
的相应实现。这看起来有点像hackish,但这里有效:
if (p.DeclaringType.IsInterface &&
typeof(T).GetInterfaces().Contains(p.DeclaringType))
{
InterfaceMapping map = typeof(T).GetInterfaceMap(p.DeclaringType);
MethodInfo getMethod = p.GetGetMethod();
for (int i = 0; i < map.InterfaceMethods.Length; i++)
{
if (map.InterfaceMethods[i] == getMethod)
{
MethodInfo target = map.TargetMethods[i];
return typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(property => property.GetGetMethod() == target);
}
}
}
p.DeclaringType == typeof(B)
其中B
是T
继承自我还没有弄清楚如何识别T
上覆盖p
基类T
中定义的虚拟属性B
的属性。< / p>
所以我的问题是
PropertyInfo
上的T
属性的p
上的B
?答案 0 :(得分:1)
我认为你错过了一个案例:T
可能只是从B
继承了属性,而没有覆盖它(除非你确定在你的特定场景中不会发生这种情况) )。
无论如何,您只需要使用typeof(T).GetProperty
按名称搜索属性,因为在给定的类中不能有2个具有相同名称的属性(与可能有多个重载的方法不同)。但是,您需要注意使用T
修饰符B
隐藏继承自new
的属性的情况。要处理这种情况,您可以检查属性的getter方法的Attributes
(使用GetGetMethod
获得):如果存在NewSlot
标志,则会隐藏继承的getter。
答案 1 :(得分:0)
我找到了回答案例3 的方法。关键是MethodInfo.GetBaseDefinition
if (typeof(T).IsSubclassOf(p.DeclaringType))
{
MethodInfo baseDefinition = p.GetGetMethod().GetBaseDefinition();
return typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(property => property.GetGetMethod().GetBaseDefinition() == baseDefinition);
}
但是,这仅适用于已在T
上覆盖的属性。
通过比较以下内容,T
是否已覆盖或未覆盖属性无关紧要:
property.GetGetMethod().GetBaseDefinition().MetadataToken == baseDefinition.MetadataToken