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?
18
A
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.
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 FieldInfo
Name
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 + ">"));
}
Thanks a lot Jason, odbłyśnik powiedział mi to samo w międzyczasie :) Gdyby pomyślał o tym wcześniej. – Zoki
@ 3o4eTo: Tylko uprzedzaj, że to nie jest głupi dowód, kruchy i prawdopodobnie nie przenośny do Mono. – jason
Zadbaj również o wyjątek, gdy nie ma żadnego gettera na nieruchomości. – nawfal