Question

Est-il possible d'ajouter des attributs à l'exécution ou de modifier la valeur d'un attribut à l'exécution?

Était-ce utile?

La solution

Les attributs sont des métadonnées statiques. Les assemblys, modules, types, membres, paramètres et valeurs de retour ne sont pas des objets de première classe en C # (par exemple, la classe System.Type est simplement une représentation réfléchie d'un type). Vous pouvez obtenir une instance d'un attribut pour un type et modifier les propriétés si elles sont accessibles en écriture, mais cela n'affectera pas l'attribut tel qu'il est appliqué au type.

Autres conseils

Cela dépend vraiment de ce que vous essayez d'accomplir.

Le System.ComponentModel.TypeDescriptor peut être utilisé pour ajouter des attributs à des types, des propriétés et des instances d'objet, et il a pour limite que vous devez également l'utiliser pour récupérer ces propriétés. Si vous écrivez le code qui utilise ces attributs et que vous pouvez respecter ces limitations, je le recommanderais certainement.

Pour autant que je sache, le contrôle PropertyGrid et la surface de conception de Visual Studio sont les seuls éléments de la BCL qui utilisent les éléments TypeDescriptor. En fait, c'est comme ça qu'ils font à peu près la moitié de ce qu'ils doivent vraiment faire.

Vous ne pouvez pas. Une solution de contournement pourrait consister à générer une classe dérivée au moment de l’exécution et à ajouter l’attribut, bien que ce soit probablement un peu exagéré.

Eh bien, juste pour être différent, j'ai trouvé un article faisant référence à l'aide de Reflection.Emit.

Voici le lien: http://www.codeproject.com/KB/cs/ dotnetattributes.aspx , vous voudrez également vous pencher sur certains des commentaires au bas de l'article, car les approches possibles sont abordées.

Non, ce n'est pas le cas.

Les attributs sont des métadonnées et sont stockés sous forme binaire dans l’assemblage compilé (c’est aussi pourquoi vous ne pouvez utiliser que des types simples).

Je ne crois pas. Même si je me trompe, le mieux que vous puissiez espérer est de les ajouter à un Type entier, jamais à une instance d'un Type.

Si vous avez besoin de quelque chose pour pouvoir ajouter dynamiquement, les attributs c # ne sont pas la solution. Regardez dans le stockage des données en XML. J'ai récemment fait un projet que j'ai commencé avec w / attributes, mais qui est finalement passé à la sérialisation w / xml.

Pourquoi avez-vous besoin de? Les attributs donnent des informations supplémentaires pour la réflexion, mais si vous savez en externe quelles propriétés vous souhaitez, vous n'en avez pas besoin.

Vous pouvez stocker les métadonnées de manière externe relativement facilement dans une base de données ou un fichier de ressources.

J'ai essayé très fort avec System.ComponentModel.TypeDescriptor sans succès. Cela ne signifie pas que cela ne fonctionne pas, mais j'aimerais voir du code pour cela.

En contrepartie, je voulais modifier certaines valeurs d'attribut. J'ai effectué 2 fonctions qui fonctionnent bien à cette fin.

        // ************************************************************************
        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, j’avais l'habitude de contourner ce problème en utilisant une carte et en implémentant ma propre conception du codage clé-valeur.

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top