una que puede programacion llamar interfaz interfaces instancia implementacion heredar declaracion declara cómo crear clase caracteristicas c# reflection explicit-interface

c# - puede - ¿Cómo uso la reflexión para obtener propiedades que implementen explícitamente una interfaz?



que es una interfaz en programacion (9)

Al código de Jacob le falta un filtro:

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

Más específicamente, si tengo:

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; } }

¿Cómo uso la reflexión para obtener todas las propiedadesInfos de las propiedades que implementan explícitamente TempInterface?

Gracias.


El getter y el setter de propiedad de una propiedad de interfaz implementada explícitamente tiene un atributo inusual. Su propiedad IsFinal es Verdadera, incluso cuando no es miembro de una clase sellada. Prueba este código para verificar mi afirmación:

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); } } }


Aquí hay una solución modificada basada en la implementación dada en esta publicación de blog :

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);


Tuve que modificar la respuesta de Jacob Carpenter, pero funciona muy bien. Nobugz también funciona, pero Jacobs es más compacto.

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


Creo que la clase que está buscando es 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)); }


¡Esto parece un poco doloroso sin razón aparente!

Mi solución es para el caso donde usted conoce el nombre de la propiedad que está buscando y es bastante simple.

Tengo una clase para hacer la reflexión un poco más fácil que solo tuve que agregar este caso a:

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); } } }

No puede hacer == en el nombre porque las propiedades implementadas explícitamente tienen nombres completamente calificados.

GetProperties necesita ambos indicadores de búsqueda para obtener propiedades privadas.


Una clase de ayuda simple que podría ayudar:

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]; } } }

Obtendrá propiedades para cada interfaz, incluso implementada explícitamente.


Basándose en la respuesta del Sr. Kurt :

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;


Es excesivamente complejo. Debe reflexionar sobre los métodos / propiedades del tipo de interfaz, ver si existen en su tipo de clase y compararlos para ver si son los "mismos" cuando existen.

Si hay algo en la interfaz pero no el tipo que está probando, es una implementación explícita. Si está en ambos, pero diferente entre los dos, es una interfaz explícita.