Domanda

È possibile aggiungere attributi in fase di esecuzione o modificare il valore di un attributo in fase di esecuzione?

È stato utile?

Soluzione

Gli attributi sono metadati statici. Assiemi, moduli, tipi, membri, parametri e valori restituiti non sono oggetti di prima classe in C # (ad esempio, la classe System.Type è semplicemente una rappresentazione riflessa di un tipo). Puoi ottenere un'istanza di un attributo per un tipo e modificare le proprietà se sono scrivibili ma ciò non influirà sull'attributo quando viene applicato al tipo.

Altri suggerimenti

Questo dipende davvero da cosa stai esattamente cercando di realizzare.

Le System.ComponentModel.TypeDescriptor possono essere usato per aggiungere attributi a tipi, proprietà ed istanze di oggetti, e ha il limite che devi usarlo per recuperare anche quelle proprietà. Se stai scrivendo il codice che consuma quegli attributi e puoi vivere entro quei limiti, lo consiglierei sicuramente.

Per quanto ne so, il controllo PropertyGrid e la superficie di progettazione dello studio visivo sono le uniche cose nel BCL che consumano le cose TypeDescriptor. In effetti, è così che fanno circa la metà delle cose che devono veramente fare.

Non puoi. Una soluzione alternativa potrebbe essere quella di generare una classe derivata in fase di runtime e aggiungere l'attributo, sebbene questo sia probabilmente un po 'eccessivo.

Beh, solo per essere diversi, ho trovato un articolo che fa riferimento a Reflection.Emit per farlo.

Ecco il link: http://www.codeproject.com/KB/cs/ dotnetattributes.aspx , vorrai anche esaminare alcuni dei commenti in fondo all'articolo, perché vengono discussi i possibili approcci.

No, non lo è.

Gli attributi sono metadati e archiviati in forma binaria nell'assieme compilato (ecco perché puoi usare solo tipi semplici in essi).

Non ci credo. Anche se sbaglio, il meglio che puoi sperare è di aggiungerli a un intero Tipo, mai una istanza di un Tipo.

Se hai bisogno di qualcosa per poterlo aggiungere dinamicamente, gli attributi c # non sono il modo giusto. Cerca nella memorizzazione dei dati in xml. Di recente ho realizzato un progetto che ho avviato con attributi, ma alla fine sono passato alla serializzazione con XML.

Perché ne hai bisogno? Gli attributi forniscono informazioni extra per la riflessione, ma se conosci esternamente quali proprietà desideri non ne hai bisogno.

È possibile memorizzare i metadati esternamente relativamente facilmente in un database o in un file di risorse.

Ho provato molto con System.ComponentModel.TypeDescriptor senza successo. Ciò non significa che non possa funzionare, ma mi piacerebbe vedere il codice per questo.

In controparte, volevo cambiare alcuni valori di Attributo. Ho fatto 2 funzioni che funzionano bene a tale scopo.

        // ************************************************************************
        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);
                }
            }
        }

In Java ero solito aggirare il problema usando una mappa e implementando il mio approccio alla codifica Key-Value.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top