Mam typ t
i chciałbym uzyskać listę właściwości publicznych, które mają atrybut MyAttribute
. Atrybut jest oznaczony AllowMultiple = false
następująco:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
Obecnie mam to, ale myślę, że jest lepszy sposób:
foreach (PropertyInfo prop in t.GetProperties())
{
object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
if (attributes.Length == 1)
{
//Property with my custom attribute
}
}
Jak mogę to poprawić? Przepraszam, jeśli to duplikat, jest mnóstwo wątków refleksyjnych ... wydaje się, że to dość gorący temat.
c#
.net
reflection
wsanville
źródło
źródło
Odpowiedzi:
Pozwala to uniknąć konieczności materializacji wystąpień atrybutów (tzn. Jest tańszy niż
GetCustomAttribute[s]()
.źródło
get
nie jest wywoływana nawet podczas używaniaGetCustomAttributes
; jednak atrybut jest tworzony w postaci instancji , co nie jest darmowe. Jeśli nie musisz sprawdzać określonych wartości atrybutu,IsDefined
jest tańszy. A w 4.5 istnieją sposoby sprawdzania danych instancji bez faktycznego tworzenia instancji atrybutów (chociaż jest to przeznaczone tylko dla bardzo specyficznych scenariuszy)Rozwiązanie, z którego najczęściej korzystam, oparte jest na odpowiedzi Tomasa Petricka. I zazwyczaj chcą coś zrobić z obu atrybutu i mienia.
źródło
O ile mi wiadomo, nie ma lepszego sposobu na mądrzejszą pracę z biblioteką Reflection. Możesz jednak użyć LINQ, aby kod był nieco ładniejszy:
Uważam, że pomaga to uporządkować kod w bardziej czytelny sposób.
źródło
Zawsze jest LINQ:
źródło
Jeśli regularnie zajmujesz się atrybutami w odbiciu, zdefiniowanie niektórych metod rozszerzenia jest bardzo, bardzo praktyczne. Zobaczysz to w wielu projektach. Ten tutaj jest tym, który często mam:
którego możesz użyć jak
typeof(Foo).HasAttribute<BarAttribute>();
Inne projekty (np. StructureMap) mają pełnoprawne klasy ReflectionHelper, które wykorzystują drzewa wyrażeń, aby mieć dokładną składnię tożsamości, np. PropertyInfos. Użycie wygląda następująco:
źródło
Oprócz poprzednich odpowiedzi: lepiej użyć metody
Any()
zamiast sprawdzania długości kolekcji:Przykład w dotnetfiddle: https://dotnetfiddle.net/96mKep
źródło
.Any()
nie sprawdza długości. Ale moja odpowiedź nie dotyczyła znalezionych właściwości z dokładnie jednym atrybutem. Po drugie, nie jestem pewien, czy poprawnie odczytałeś kod -.Any
metoda wywołana na wynikuGetCustomAttrubutes
metody. Tak więc typempropertiesWithMyAttribute
będzie kolekcja właściwości. Sprawdź przykład w dotnetfiddle (dodaję link do odpowiedzi).