Frage

Ist es möglich, Attribute zur Laufzeit hinzuzufügen oder den Wert eines Attributs zur Laufzeit zu ändern?

War es hilfreich?

Lösung

Attribute sind statische Metadaten. Baugruppen, Module, Typen, Mitglieder, Parameter und Rückgabewerte sind nicht erstklassige Objekte in C # (z.B. die System.Type Klasse ist lediglich eine Darstellung eines reflektierten Typ). Sie können eine Instanz eines Attributs für einen Typ erhalten und die Eigenschaften ändern, wenn sie beschreibbar sind, aber das wird nicht das Attribut beeinflussen, wie es auf den Typ angewendet wird.

Andere Tipps

Das hängt davon ab, was genau Sie versuchen zu erreichen.

Die System.ComponentModel.TypeDescriptor stopfen verwendet werden Attribute Typen, Eigenschaften und Objektinstanzen hinzuzufügen, und es hat die Einschränkung, dass Sie es zu benutzen, diese Eigenschaften auch abzurufen. Wenn Sie den Code schreiben, die diese Attribute verbraucht, und Sie können innerhalb dieser Grenzen leben, dann würde ich es auf jeden Fall vorschlagen.

Soweit ich weiß, die Property Kontrolle und die Visual Studio-Design-Oberfläche sind die einzigen Dinge in der BCL, die die TypeDescriptor Sachen verbrauchen. In der Tat, das ist, wie sie die Hälfte haben über das, was sie wirklich tun müssen.

Sie können nicht. Eine Abhilfe könnte sein, eine abgeleitete Klasse zur Laufzeit zu generieren und das Hinzufügen des Attributs, obwohl dies wahrscheinlich etwas zuviel des Guten.

Nun, nur anders zu sein, fand ich einen Artikel, die Reflection.Emit referenzen verwenden, dies zu tun.

Hier ist der Link: http://www.codeproject.com/KB/cs/ dotnetattributes.aspx , Sie wollen auch am Ende des Artikels in einige der Kommentare schauen, weil mögliche Ansätze diskutiert werden.

Nein, es ist nicht.

Attribute sind Meta-Daten und in binär-Form in der kompilierten Assembly gespeichert (das ist auch, warum Sie nur einfache Typen in Anspruch genommen werden kann).

Ich glaube nicht. Auch wenn ich falsch bin, das Beste, was Sie für hoffen können, ist, sie zu einer ganzen Art hinzufügen, nie eine Instanz von einem Typ.

Wenn Sie etwas müssen in der Lage sein, dynamisch hinzugefügt, c # Attribute sind nicht der richtige Weg. Schauen Sie in die XML-Daten in Speichern. Ich habe vor kurzem ein Projekt, das ich w / Attribute gestartet, aber schließlich bewegt w / xml Serialisierung.

Warum brauchen Sie? Attribute geben zusätzliche Informationen zum Nachdenken, aber wenn man von außen wissen, welche Eigenschaften Sie möchten, dass Sie brauchen sie nicht.

Sie könnten Meta-Daten extern speichern relativ einfach in einer Datenbank oder Ressourcendatei.

Ich habe versucht, sehr hart mit System.ComponentModel.TypeDescriptor ohne Erfolg. Das macht bedeutet nicht, dass es nicht funktionieren kann, aber ich mag Code für das sehen.

Im Gegenstück, wollte ich einige Attributwerte ändern. Ich habe zwei Funktionen, die für diesen Zweck gut funktionieren.

        // ************************************************************************
        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 habe ich durch die Verwendung einer Karte, dies zu umgehen und meine eigene Version der Umsetzung auf Schlüsselwert-Codierung.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top