Eu tenho um tipo, t
e eu gostaria de obter uma lista das propriedades públicas que tenham o atributo MyAttribute
. O atributo é marcado com AllowMultiple = false
, assim:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
Atualmente, o que tenho é isso, mas estou pensando que há uma maneira melhor:
foreach (PropertyInfo prop in t.GetProperties())
{
object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
if (attributes.Length == 1)
{
//Property with my custom attribute
}
}
Como posso melhorar isso? Peço desculpas se esta é uma duplicata, há uma tonelada de tópicos de reflexão por aí ... parece que é um assunto bastante quente.
c#
.net
reflection
Wesville
fonte
fonte
Respostas:
Isso evita a necessidade de materializar quaisquer instâncias de atributo (ou seja, é mais barato que
GetCustomAttribute[s]()
.fonte
get
não é chamada mesmo ao usarGetCustomAttributes
; no entanto, o atributo é instanciado , o que não é gratuito. Se você não precisar verificar valores específicos do atributo,IsDefined
é mais barato. E em 4,5, existem maneiras de verificar os dados instanciação sem realmente criar quaisquer instâncias de atributos (embora este seja destinado para cenários muito específicos apenas)A solução que eu mais uso é baseada na resposta de Tomas Petricek. Normalmente, eu quero fazer algo com tanto o atributo e propriedade.
fonte
Até onde eu sei, não há maneira melhor de trabalhar com a biblioteca Reflection de maneira mais inteligente. No entanto, você pode usar o LINQ para tornar o código um pouco melhor:
Acredito que isso ajude você a estruturar o código de maneira mais legível.
fonte
Sempre há LINQ:
fonte
Se você lida regularmente com Atributos em reflexão, é muito, muito prático definir alguns métodos de extensão. Você verá isso em muitos projetos por aí. Este aqui é um que eu geralmente tenho:
que você pode usar como
typeof(Foo).HasAttribute<BarAttribute>();
Outros projetos (por exemplo, StructureMap) possuem classes ReflectionHelper de pleno direito que usam árvores de Expressão para ter uma sintaxe fina de identidade, por exemplo, PropertyInfos. O uso fica assim:
fonte
Além das respostas anteriores: é melhor usar o método
Any()
do que verificar o tamanho da coleção:O exemplo em dotnetfiddle: https://dotnetfiddle.net/96mKep
fonte
.Any()
não verifica o comprimento. Mas minha resposta não foi sobre propriedades encontradas com exatamente um atributo. Segundo, não tenho certeza de que você leu o código corretamente -.Any
método chamado no resultado doGetCustomAttrubutes
método. Portanto, o tipo dopropertiesWithMyAttribute
será a coleção das propriedades. Confira o exemplo em dotnetfiddle (adiciono o link à resposta).