Tengo un tipo, t
y me gustaría obtener una lista de las propiedades públicas que tienen el atributo MyAttribute
. El atributo está marcado con AllowMultiple = false
, así:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
Actualmente lo que tengo es esto, pero creo que hay una mejor manera:
foreach (PropertyInfo prop in t.GetProperties())
{
object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
if (attributes.Length == 1)
{
//Property with my custom attribute
}
}
¿Cómo puedo mejorar esto? Mis disculpas si esto es un duplicado, hay un montón de hilos de reflexión por ahí ... parece que es un tema bastante candente.
c#
.net
reflection
wsanville
fuente
fuente
Respuestas:
Esto evita tener que materializar cualquier instancia de atributo (es decir, es más barato que
GetCustomAttribute[s]()
.fuente
get
no se llama incluso cuando se usaGetCustomAttributes
; sin embargo, el atributo es instanciado , lo que no es gratuito. Si no necesita verificar valores específicos del atributo,IsDefined
es más barato. Y en 4.5, hay maneras de comprobar los datos de creación de instancias y sin crear realmente cualquier instancia de atributos (aunque esto está destinado para escenarios muy específicos)La solución que más utilizo se basa en la respuesta de Tomas Petricek. Por lo general quiero hacer algo con tanto el atributo y la propiedad.
fuente
Hasta donde sé, no hay mejor manera de trabajar con la biblioteca Reflection de una manera más inteligente. Sin embargo, podría usar LINQ para que el código sea un poco más agradable:
Creo que esto te ayuda a estructurar el código de una manera más legible.
fuente
Siempre hay LINQ:
fuente
Si trata regularmente con Atributos en Reflection, es muy, muy práctico definir algunos métodos de extensión. Verá eso en muchos proyectos por ahí. Este de aquí es uno que a menudo tengo:
que puedes usar como
typeof(Foo).HasAttribute<BarAttribute>();
Otros proyectos (p. Ej., StructureMap) tienen clases ReflectionHelper completas que utilizan árboles de expresión para tener una sintaxis precisa para la identidad, p. Ej. PropertyInfos. El uso entonces se ve así:
fuente
Además de las respuestas anteriores: es mejor usar el método en
Any()
lugar de verificar la longitud de la colección:El ejemplo en dotnetfiddle: https://dotnetfiddle.net/96mKep
fuente
.Any()
no verifica la longitud. Pero mi respuesta no fue sobre propiedades encontradas con exactamente un atributo. En segundo lugar, no estoy seguro de que haya leído el código correctamente,.Any
método llamado en el resultado delGetCustomAttrubutes
método. Entonces el tipo depropertiesWithMyAttribute
será la colección de las propiedades. Mira el ejemplo en dotnetfiddle (agrego el enlace a la respuesta).