¿Cómo puedo determinar si una propiedad fue anulada?

Estoy haciendo un proyecto en el que necesito registrar todas las propiedades, debido a que el sistema es tan grande que se requeriría mucho trabajo para registrar todas las propiedades de las que quiero depender para Xaml.

El objective es encontrar todas las propiedades que están en la parte superior del árbol.

así que básicamente

public class A{ public int Property1 { get; set; } } public class B : A{ public int Property2 { get; set; } public virtual int Property3 { get; set; } } public class C : B{ public override int Property3 { get; set; } public int Property4 { get; set; } public int Property5 { get; set; } } 

El resultado final sería algo como esto.

 A.Property1 B.Property2 B.Property3 C.Property4 C.Property5 

Si nota que no quiero aceptar propiedades anuladas debido a la forma en que busco las propiedades si hago algo como esto

C.Property3, por ejemplo, y no puede encontrarlo, verificará el tipo de letra de C y allí lo encontrará.

Esto es lo que tengo hasta ahora.

 public static void RegisterType( Type type ) { PropertyInfo[] properties = type.GetProperties( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.GetProperty | BindingFlags.SetProperty ); if ( properties != null && properties.Length > 0 ) { foreach ( PropertyInfo property in properties ) { // if the property is an indexers then we ignore them if ( property.Name == "Item" && property.GetIndexParameters().Length > 0 ) continue; // We don't want Arrays or Generic Property Types if ( (property.PropertyType.IsArray || property.PropertyType.IsGenericType) ) continue; // Register Property } } } 

Lo que quiero son los siguientes:

  • Propiedades públicas, que no están anuladas, ni estáticas, ni privadas
  • Se permiten las propiedades get y set
  • No son una matriz o un tipo genérico
  • Son la parte superior del árbol, es decir, la clase C en el ejemplo es la más alta (el ejemplo de la lista de propiedades es exactamente lo que estoy buscando)
  • No son una propiedad de indexador (este [índice])

Para ignorar los miembros heredados, puede usar el indicador BindingFlags.DeclaredOnly, que ya está haciendo.

Pero cuando las propiedades se anulan, la clase derivada las vuelve a declarar. El truco consiste en observar sus métodos de acceso para determinar si en realidad están anulados.

 Type type = typeof(Foo); foreach ( var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { var getMethod = property.GetGetMethod(false); if (getMethod.GetBaseDefinition() == getMethod) { Console.WriteLine(getMethod); } } 

Si la propiedad se invalida, su Información de método ‘getter’ devolverá una Información de GetBaseDefinition diferente de GetBaseDefinition .

Ninguna de estas soluciones funcionó bien en mi caso. Terminé usando DeclaringType para determinar la diferencia en las definiciones (he proporcionado la función completa para dar algo de contexto):

 static public String GetExpandedInfo(Exception e) { StringBuilder info = new StringBuilder(); Type exceptionType = e.GetType(); // only get properties declared in this type (ie not inherited from System.Exception) PropertyInfo[] propertyInfo = exceptionType.GetProperties(System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); if (propertyInfo.Length > 0) { // add the exception class name at the top info.AppendFormat("[{0}]\n", exceptionType.Name); foreach (PropertyInfo prop in propertyInfo) { // check the property isn't overriding a System.Exception property (ie Message) // as that is a default property accessible via the generic Exception class handlers var getMethod = prop.GetGetMethod(false); if (getMethod.GetBaseDefinition().DeclaringType == getMethod.DeclaringType) { // add the property name and it's value info.AppendFormat("{0}: {1}\n", prop.Name, prop.GetValue(e, null)); } } } 

Puede usar property.DeclaringType para verificar qué tipo declaró la propiedad. Si es diferente al tipo en el que está reflexionando actualmente, está anulado.

Se ha señalado que un tipo de anulación redeclará la propiedad. No pensé en eso. Supongo que tienes que atravesar los tipos de base para ver si declararon una propiedad con el mismo nombre. Entonces, si se declara en el tipo reflejado Y por una clase base, ¿está anulada?

Oh Josh ya lo señaló … 🙂