Come ottenere un elenco di proprietà con un determinato attributo?


210

Ho un tipo te vorrei ottenere un elenco delle proprietà pubbliche che hanno l'attributo MyAttribute. L'attributo è contrassegnato con AllowMultiple = false, in questo modo:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]

Attualmente quello che ho è questo, ma sto pensando che c'è un modo migliore:

foreach (PropertyInfo prop in t.GetProperties())
{
    object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
    if (attributes.Length == 1)
    {
         //Property with my custom attribute
    }
}

Come posso migliorare questo? Mi scuso se questo è un duplicato, ci sono un sacco di fili di riflessione là fuori ... sembra che sia un argomento piuttosto caldo.


No. È necessario un PropertyInfo prima di sapere se la proprietà ha un attributo.
Hans Passant,

Risposte:


391
var props = t.GetProperties().Where(
                prop => Attribute.IsDefined(prop, typeof(MyAttribute)));

Questo evita di dover materializzare qualsiasi istanza di attributo (cioè è più economico di GetCustomAttribute[s]().


1
Buon consiglio Avrò comunque bisogno dell'istanza dell'attributo, ma mi piace.
wsanville,

1
Stavo solo cercando un modo per verificare l'esistenza di un attributo senza l'effetto collaterale che viene chiamato la proprietà get. Grazie Marc, funziona!
Örjan Jämte,

1
@ ÖrjanJämte la proprietà getnon viene chiamata anche durante l'utilizzo GetCustomAttributes; tuttavia, l'attributo viene istanziato , il che non è gratuito. Se non è necessario controllare valori specifici dell'attributo, IsDefinedè più economico. E in 4.5, ci sono modi per controllare i dati di istanza senza effettivamente creare istanze di attributo (anche se questo è destinato solo a scenari molto specifici)
Marc Gravell


2
per dotnet core: var props = t.GetProperties (). Where (e => e.IsDefined (typeof (MyAttribute)));
Rtype,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.