2010-02-05 4 views
18

Tak więc w moim przypadku robię odkrycie struktury klasy za pomocą refleksji. Muszę być w stanie dowiedzieć się, czy właściwość jest zaimplementowaną automatycznie przez obiekt PropertyInfo. Zakładam, że odbicie API nie ujawnia takiej funkcjonalności, ponieważ właściwości automatyczne są zależne od C#, ale czy istnieje jakieś obejście tego problemu?Jak sprawdzić, czy właściwość jest autorską właściwością z odbiciem?

Odpowiedz

16

Można sprawdzić, czy metoda get lub set jest oznaczona atrybutem CompilerGenerated. Następnie można połączyć to z szukaniem prywatnego pola, które jest oznaczone atrybutem CompilerGenerated zawierającym nazwę właściwości i ciąg "BackingField".

Może:

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

To nie jest głupi dowód, dość kruche i prawdopodobnie nie przenośny do, powiedzmy, Mono.

+0

Thanks a lot Jason, odbłyśnik powiedział mi to samo w międzyczasie :) Gdyby pomyślał o tym wcześniej. – Zoki

+1

@ 3o4eTo: Tylko uprzedzaj, że to nie jest głupi dowód, kruchy i prawdopodobnie nie przenośny do Mono. – jason

+0

Zadbaj również o wyjątek, gdy nie ma żadnego gettera na nieruchomości. – nawfal

7

ten powinien zrobić:

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

Powodem jest to, że do automatycznego właściwości własność podkładzie FieldInfoName wyglądałby następująco:

<PropertName>k__BackingField 

Ponieważ znaki < i > nie pojawiają w przypadku normalnych pól pole z takim nazewnictwem wskazuje na pole zaplecza automatycznej właściwości. Jak mówi Jason, wciąż jest krucha.

Albo zrobić to odrobinę szybciej,

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