Pregunta

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

¿Fue útil?

Solución

Los atributos son metadatos estáticos. Los ensamblados, 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 pueden escribirse, pero eso no afectará el atributo ya que se aplica al tipo.

Otros consejos

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

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

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

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.

Bueno, 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á ver algunos de los comentarios al final del artículo, porque se discuten los posibles enfoques.

No, no lo es.

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

No lo creo. Incluso si me equivoco, lo mejor que puede esperar es agregarlos a un Tipo completo, nunca una instancia de un Tipo.

Si necesita algo para poder agregar dinámicamente, los atributos de c # no son la manera. Busque almacenar los datos en xml. Hace poco hice un proyecto que comencé con w / atributos, pero finalmente me mudé a serialización con w / xml.

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

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

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

En la contraparte, 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 usando un mapa e implementando mi propia versión de la codificación Key-Value.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top