More specifically, if I have:
更具体地说,如果我有:
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;
}
}
How do I use reflection to get all the propertyInfos for properties explicitly implementing TempInterface?
如何使用反射来获取显式实现TempInterface的属性的所有propertyInfos?
Thanks.
9 个解决方案
#1
20
I think the class you are looking for is System.Reflection.InterfaceMapping.
我认为您正在寻找的类是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));
}
#2
4
The property getter and setter of an explicitly implemented interface property has an unusual attribute. It's IsFinal property is True, even when it is not a member of a sealed class. Try this code to verify my assertion:
显式实现的接口属性的属性getter和setter具有不寻常的属性。它的IsFinal属性是True,即使它不是密封类的成员。试试这段代码来验证我的断言:
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);
}
}
}
#3
3
Building on the answer by MrKurt:
在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;
#4
2
Here's a modified solution based on the implementation given in this blog post:
以下是基于此博客文章中给出的实现的修改后的解决方案:
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);
#5
1
I had to modify Jacob Carpenter's answer but it works nicely. nobugz's also works but Jacobs is more compact.
我不得不修改Jacob Carpenter的答案,但效果很好。 nobugz也有效,但Jacobs更紧凑。
var explicitProperties =
from method in typeof(TempClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
where method.IsFinal && method.IsPrivate
select method;
#6
1
It's overly complex. You have to reflect over the methods/properties of the Interface type, see if they exist in your class type, and compare them to see if they're the "same" when they do exist.
这太复杂了。您必须反思Interface类型的方法/属性,看看它们是否存在于您的类类型中,并比较它们以确定它们是否存在时是否“相同”。
If something is in the interface but not the type you're testing, it's an explicit implementation. If it's in both, but different between the two, it's an explicit interface.
如果界面中有某些内容但不是您正在测试的类型,则它是一个显式实现。如果它在两者之间,但两者之间有所不同,那么它就是一个明确的界面。
#7
0
Jacob's code is missing a filter:
雅各布的代码缺少一个过滤器:
var props = typeof(TempClass).GetInterfaces().Where(i => i.Name=="TempInterface").SelectMany(i => i.GetProperties());
foreach (var prop in props)
Console.WriteLine(prop);
#8
0
This seems a bit painful for no apparent reason!
没有明显的理由,这似乎有点痛苦!
My solution is for the case where you know the name of the property you are looking for and is pretty simple.
我的解决方案是您知道要查找的属性的名称并且非常简单的情况。
I have a class for making reflection a bit easier that I just had to add this case to:
我有一个让反射更容易的类,我只需要将这个案例添加到:
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); }
}
}
You cant just do == on name because explicitly implemented properties have fully qualified names.
您不能在名称上执行==因为显式实现的属性具有完全限定名称。
GetProperties needs both the search flags to get at private properties.
GetProperties需要两个搜索标志来获取私有属性。
#9
0
A simple helper class that could help:
一个简单的帮助类,可以帮助:
public class InterfacesPropertiesMap
{
private readonly Dictionary<Type, PropertyInfo[]> map;
public InterfacesPropertiesMap(Type type)
{
this.Interfaces = type.GetInterfaces();
var properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
this.map = new Dictionary<Type, PropertyInfo[]>(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]; }
}
}
You'll get properties for each interface, even explicitly implemented.
您将获得每个接口的属性,甚至是明确实现的。
#1
20
I think the class you are looking for is System.Reflection.InterfaceMapping.
我认为您正在寻找的类是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));
}
#2
4
The property getter and setter of an explicitly implemented interface property has an unusual attribute. It's IsFinal property is True, even when it is not a member of a sealed class. Try this code to verify my assertion:
显式实现的接口属性的属性getter和setter具有不寻常的属性。它的IsFinal属性是True,即使它不是密封类的成员。试试这段代码来验证我的断言:
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);
}
}
}
#3
3
Building on the answer by MrKurt:
在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;
#4
2
Here's a modified solution based on the implementation given in this blog post:
以下是基于此博客文章中给出的实现的修改后的解决方案:
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);
#5
1
I had to modify Jacob Carpenter's answer but it works nicely. nobugz's also works but Jacobs is more compact.
我不得不修改Jacob Carpenter的答案,但效果很好。 nobugz也有效,但Jacobs更紧凑。
var explicitProperties =
from method in typeof(TempClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
where method.IsFinal && method.IsPrivate
select method;
#6
1
It's overly complex. You have to reflect over the methods/properties of the Interface type, see if they exist in your class type, and compare them to see if they're the "same" when they do exist.
这太复杂了。您必须反思Interface类型的方法/属性,看看它们是否存在于您的类类型中,并比较它们以确定它们是否存在时是否“相同”。
If something is in the interface but not the type you're testing, it's an explicit implementation. If it's in both, but different between the two, it's an explicit interface.
如果界面中有某些内容但不是您正在测试的类型,则它是一个显式实现。如果它在两者之间,但两者之间有所不同,那么它就是一个明确的界面。
#7
0
Jacob's code is missing a filter:
雅各布的代码缺少一个过滤器:
var props = typeof(TempClass).GetInterfaces().Where(i => i.Name=="TempInterface").SelectMany(i => i.GetProperties());
foreach (var prop in props)
Console.WriteLine(prop);
#8
0
This seems a bit painful for no apparent reason!
没有明显的理由,这似乎有点痛苦!
My solution is for the case where you know the name of the property you are looking for and is pretty simple.
我的解决方案是您知道要查找的属性的名称并且非常简单的情况。
I have a class for making reflection a bit easier that I just had to add this case to:
我有一个让反射更容易的类,我只需要将这个案例添加到:
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); }
}
}
You cant just do == on name because explicitly implemented properties have fully qualified names.
您不能在名称上执行==因为显式实现的属性具有完全限定名称。
GetProperties needs both the search flags to get at private properties.
GetProperties需要两个搜索标志来获取私有属性。
#9
0
A simple helper class that could help:
一个简单的帮助类,可以帮助:
public class InterfacesPropertiesMap
{
private readonly Dictionary<Type, PropertyInfo[]> map;
public InterfacesPropertiesMap(Type type)
{
this.Interfaces = type.GetInterfaces();
var properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
this.map = new Dictionary<Type, PropertyInfo[]>(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]; }
}
}
You'll get properties for each interface, even explicitly implemented.
您将获得每个接口的属性,甚至是明确实现的。