2010-02-05 13 views

Respuesta

16

Puede verificar si el método get o set está marcado con el atributo CompilerGenerated. A continuación, puede combinar eso con la búsqueda de un campo privado marcado con el atributo CompilerGenerated que contiene el nombre de la propiedad y la cadena "BackingField".

Tal vez:

public static bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty(
    this PropertyInfo info 
) { 
    bool mightBe = info.GetGetMethod() 
         .GetCustomAttributes(
          typeof(CompilerGeneratedAttribute), 
          true 
         ) 
         .Any(); 
    if (!mightBe) { 
     return false; 
    } 


    bool maybe = info.DeclaringType 
        .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
        .Where(f => f.Name.Contains(info.Name)) 
        .Where(f => f.Name.Contains("BackingField")) 
        .Where(
         f => f.GetCustomAttributes(
          typeof(CompilerGeneratedAttribute), 
          true 
         ).Any() 
        ) 
        .Any(); 

     return maybe; 
    } 

No es a toda prueba, bastante frágil y probablemente no portátil para, por ejemplo, Mono.

+0

Muchas gracias Jason, el reflector me dijo lo mismo en el ínterin :) Debería haber pensado en ello antes. – Zoki

+1

@ 3o4eTo: Solo tenga en cuenta que esto no es a prueba de tontos, quebradizo y posiblemente no portátil para Mono. – jason

+0

También cuide la excepción cuando no hay captadores en la propiedad. – nawfal

7

Esto debería hacer:

public static bool IsAutoProperty(this PropertyInfo prop) 
{ 
    return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
          .Any(f => f.Name.Contains("<" + prop.Name + ">")); 
} 

La razón es que para la auto-properties la propiedad Name del respaldo FieldInfo se vería así:

<PropertName>k__BackingField 

Desde caracteres < y > no aparecería para los campos normales, un campo con ese tipo de nomenclatura apunta a un campo de respaldo de una propiedad automática. Como dice Jason, todavía es frágil.

O para que sea un poco más rápido,

public static bool IsAutoProperty(this PropertyInfo prop) 
{ 
    if (!prop.CanWrite || !prop.CanRead) 
     return false; 

    return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
          .Any(f => f.Name.Contains("<" + prop.Name + ">")); 
} 
Cuestiones relacionadas