153 Stimmen

Können Attribute in C# dynamisch hinzugefügt werden?

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

0 Stimmen

3voto

Joel Coehoorn Punkte 377088

Das glaube ich nicht. Selbst wenn ich mich irre, können Sie bestenfalls hoffen, dass sie einem ganzen Typus hinzugefügt werden, niemals einem Instanz eines Typs.

3voto

Darren Kopp Punkte 74401

Wenn Sie etwas brauchen, um dynamisch hinzugefügt werden zu können, sind c#-Attribute nicht der richtige Weg. Schauen Sie in die Speicherung der Daten in Xml. Ich habe vor kurzem ein Projekt, das ich w / Attribute gestartet, aber schließlich verschoben, um Serialisierung w / xml.

3voto

Keith Punkte 141163

Warum brauchen Sie das? Attribute geben zusätzliche Informationen für die Reflexion, aber wenn man von außen weiß, welche Eigenschaften man will, braucht man sie nicht.

Sie können Metadaten relativ einfach extern in einer Datenbank oder einer Ressourcendatei speichern.

1voto

Eric Ouellet Punkte 9965

Wie in einem Kommentar von Deczaloth unten erwähnt, denke ich, dass Metadaten zur Kompilierungszeit festgelegt werden. Ich erreiche dies, indem ich ein dynamisches Objekt erstelle, in dem ich GetType() überschreibe oder GetCustomType() verwende und meinen eigenen Typ schreibe. Auf diese Weise könnte man dann...

Ich versuchte sehr hart mit System.ComponentModel.TypeDescriptor ohne Erfolg. Das bedeutet nicht, dass es nicht funktionieren kann, aber ich würde gerne Code für das sehen.

Im Gegenstück wollte ich einige Attributwerte ändern. Ich habe 2 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);
                }
            }
        }

-9voto

Daniel Honig Punkte 4063

In Java habe ich dieses Problem durch die Verwendung einer Map und die Implementierung meiner eigenen Variante der Schlüssel-Wert-Kodierung umgangen.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X