¿Se pueden agregar atributos dinámicamente en C #?

¿Es posible agregar atributos en tiempo de ejecución o cambiar el valor de un atributo en tiempo de ejecución?

Los atributos son metadatos estáticos. Los ensamblajes, módulos, tipos, miembros, parámetros y valores de retorno no son objetos de primera clase en C # (por ejemplo, la clase System.Type es simplemente una representación reflejada de un tipo). Puede obtener una instancia de un atributo para un tipo y cambiar las propiedades si son modificables, pero eso no afectará al atributo a medida que se aplica al tipo.

Esto realmente depende de qué es exactamente lo que estás tratando de lograr.

El material System.ComponentModel.TypeDescriptor se puede usar para agregar atributos a tipos, propiedades e instancias de objeto, y tiene la limitación de que debe usarse para recuperar esas propiedades también. Si estás escribiendo el código que consume esos atributos, y puedes vivir dentro de esas limitaciones, entonces definitivamente lo sugeriría.

Hasta donde yo sé, el control PropertyGrid y la superficie de diseño de estudio visual son las únicas cosas en el BCL que consumen las cosas de TypeDescriptor. De hecho, así es como hacen la mitad de las cosas que realmente necesitan hacer.

Bueno, solo para ser diferente, encontré un artículo que hace referencia al uso de Reflection.Emit para hacerlo.

Aquí está el enlace: http://www.codeproject.com/KB/cs/dotnetattributes.aspx , también querrá examinar algunos de los comentarios al final del artículo, porque se discuten posibles enfoques.

No puedes. Una solución alternativa podría ser generar una clase derivada en tiempo de ejecución y agregar el atributo, aunque esto probablemente sea una exageración.

No, no es.

Los atributos son metadatos y se almacenan en forma binaria en el ensamblado comstackdo (es por eso que solo se pueden usar tipos simples en ellos).

Yo no lo creo. Incluso si estoy equivocado, lo mejor que puedes esperar es agregarlos a un tipo completo, nunca a una instancia de un tipo.

Si necesita algo que se pueda agregar dinámicamente, los atributos de c # no son el camino. Busca almacenar los datos en xml. Recientemente realicé un proyecto que comencé con atributos, pero finalmente pasé a la serialización w / xml.

¿Por qué lo necesitas? Los atributos brindan información adicional para la reflexión, pero si conoce externamente qué propiedades desea, no las necesita.

Puede almacenar metadatos externamente de forma relativamente fácil en una base de datos o archivo de recursos.

Intenté muy duro con System.ComponentModel.TypeDescriptor sin éxito. Eso no significa que no funcione, pero me gustaría ver el código para eso.

En la parte contraria, quería cambiar algunos valores de atributo. Hice 2 funciones que funcionan bien para ese propósito.

  // ************************************************************************ public static void SetObjectPropertyDescription(this Type typeOfObject, string propertyName, string description) { PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName]; var att = pd.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute; if (att != null) { var fieldDescription = att.GetType().GetField("description", BindingFlags.NonPublic | BindingFlags.Instance); if (fieldDescription != null) { fieldDescription.SetValue(att, description); } } } // ************************************************************************ public static void SetPropertyAttributReadOnly(this Type typeOfObject, string propertyName, bool isReadOnly) { PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName]; var att = pd.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute; if (att != null) { var fieldDescription = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance); if (fieldDescription != null) { fieldDescription.SetValue(att, isReadOnly); } } } 

En Java solía solucionar esto utilizando un mapa e implementando mi propia versión de encoding Key-Value.

http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html