如何使用reflection来获取显式实现接口的属性?

更具体地说,如果我有:

public class TempClass : TempInterface { int TempInterface.TempProperty { get; set; } int TempInterface.TempProperty2 { get; set; } public int TempProperty { get; set; } } public interface TempInterface { int TempProperty { get; set; } int TempProperty2 { get; set; } } 

如何使用reflection来获取显式实现TempInterface的属性的所有propertyInfos?

谢谢。

我认为您正在寻找的类是System.Reflection.InterfaceMapping。

 Type ifaceType = typeof(TempInterface); Type tempType = typeof(TempClass); InterfaceMapping map = tempType.GetInterfaceMap(ifaceType); for (int i = 0; i < map.InterfaceMethods.Length; i++) { MethodInfo ifaceMethod = map.InterfaceMethods[i]; MethodInfo targetMethod = map.TargetMethods[i]; Debug.WriteLine(String.Format("{0} maps to {1}", ifaceMethod, targetMethod)); } 

显式实现的接口属性的属性getter和setter具有不寻常的属性。 它的IsFinal属性是True,即使它不是密封类的成员。 试试这段代码来validation我的断言:

  foreach (AssemblyName name in Assembly.GetEntryAssembly().GetReferencedAssemblies()) { Assembly asm = Assembly.Load(name); foreach (Type t in asm.GetTypes()) { if (t.IsAbstract) continue; foreach (MethodInfo mi in t.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)) { int dot = mi.Name.LastIndexOf('.'); string s = mi.Name.Substring(dot + 1); if (!s.StartsWith("get_") && !s.StartsWith("set_")) continue; if (mi.IsFinal) Console.WriteLine(mi.Name); } } } 

在MrKurt回答的基础上 :

 var targetMethods = from iface in typeof(TempClass).GetInterfaces() from method in typeof(TempClass).GetInterfaceMap(iface).TargetMethods select method; var explicitProps = from prop in typeof(TempClass).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic) where targetMethods.Contains(prop.GetGetMethod(true)) || targetMethods.Contains(prop.GetSetMethod(true)) select prop; 

以下是基于此博客文章中给出的实现的修改后的解决方案:

 var explicitProperties = from prop in typeof(TempClass).GetProperties( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) let getAccessor = prop.GetGetMethod(true) where getAccessor.IsFinal && getAccessor.IsPrivate select prop; foreach (var p in explicitProperties) Console.WriteLine(p.Name); 

我不得不修改Jacob Carpenter的答案,但效果很好。 nobugz也有效,但Jacobs更紧凑。

 var explicitProperties = from method in typeof(TempClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance) where method.IsFinal && method.IsPrivate select method; 

这太复杂了。 您必须反思Interface类型的方法/属性,看看它们是否存在于您的类类型中,并比较它们以确定它们是否存在时是否“相同”。

如果界面中有某些内容但不是您正在测试的类型,则它是一个显式实现。 如果它在两者之间,但两者之间有所不同,那么它就是一个明确的界面。

雅各布的代码缺少一个filter:

  var props = typeof(TempClass).GetInterfaces().Where(i => i.Name=="TempInterface").SelectMany(i => i.GetProperties()); foreach (var prop in props) Console.WriteLine(prop); 

没有明显的理由,这似乎有点痛苦!

我的解决方案是您知道要查找的属性的名称并且非常简单的情况。

我有一个让reflection更容易的类,我只需要将这个案例添加到:

 public class PropertyInfoWrapper { private readonly object _parent; private readonly PropertyInfo _property; public PropertyInfoWrapper(object parent, string propertyToChange) { var type = parent.GetType(); var privateProperties= type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance); var property = type.GetProperty(propertyToChange) ?? privateProperties.FirstOrDefault(p => UnQualifiedNameFor(p) == propertyName); if (property == null) throw new Exception(string.Format("cant find property |{0}|", propertyToChange)); _parent = parent; _property = property; } private static string UnQualifiedNameFor(PropertyInfo p) { return p.Name.Split('.').Last(); } public object Value { get { return _property.GetValue(_parent, null); } set { _property.SetValue(_parent, value, null); } } } 

您不能在名称上执行==因为显式实现的属性具有完全限定名称。

GetProperties需要两个搜索标志来获取私有属性。

一个简单的帮助类,可以帮助:

 public class InterfacesPropertiesMap { private readonly Dictionary map; public InterfacesPropertiesMap(Type type) { this.Interfaces = type.GetInterfaces(); var properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); this.map = new Dictionary(this.Interfaces.Length); foreach (var intr in this.Interfaces) { var interfaceMap = type.GetInterfaceMap(intr); this.map.Add(intr, properties.Where(p => interfaceMap.TargetMethods .Any(t => t == p.GetGetMethod(true) || t == p.GetSetMethod(true))) .Distinct().ToArray()); } } public Type[] Interfaces { get; private set; } public PropertyInfo[] this[Type interfaceType] { get { return this.map[interfaceType]; } } } 

您将获得每个接口的属性,甚至是明确实现的。