2010-02-24 11 views
43

Ich habe gehört, wie Leute sagen, ein paar verschiedene Dinge über das DefaultValue Attribut einschließlich: „Es setzt den Wert der Eigenschaft, bevor irgendetwas verwendet es sonst“.NET Default Attribut

  • "Es funktioniert nicht für autoproperties."
  • "Es ist nur für Dekoration. Sie müssen die tatsächlichen Standardwerte manuell festlegen."

Welche (wenn überhaupt) ist richtig? Setzt DefaultValue tatsächlich Standardwerte? Gibt es Fälle, in denen es nicht funktioniert? Ist es am besten, es nicht zu benutzen?

Antwort

45

Der Ort, an dem ich normalerweise DefaultValue verwendet, ist für Klassen, die in XML serialisiert/deserialisiert sind. Es nicht den Standardwert während der Instanziierung festlegen und keinen Einfluss auf autoproperties.

Von MSDN:

A Default wird kein Mitglied verursacht automatisch mit dem Wert des Attributs initialisiert werden. Sie müssen den Anfangswert in Ihrem Code festlegen.

MSDN - DefaultValueAttribute Class


Edit: Wie Roland weist darauf hin, und wie in ihren Antworten erwähnt andere das Attribut auch durch den Formular-Designer verwendet wird

+0

Gut zu wissen. Vielen Dank! – Aaron

+1

Vergessen Sie nicht, dass der Formular-Designer es auch verwendet ... –

1

„Es setzt den Wert der Immobilie vor alles andere nutzt es. " -> Nein der Standardwert ist nur für den Designer. Ein Standardwert wird nicht in den Designercode übernommen.

"Es funktioniert nicht für autoproperties." -> Nein

"Es ist nur für die Dekoration. Sie müssen die tatsächlichen Standardwerte manuell festlegen." -> Nein. Wegen der Designer-Serialisierung. Aber Sie müssen es manuell einstellen.

11

Wie alle Attribute sind es Metadaten, und als solche "Es ist nur für Dekoration. Sie müssen die tatsächlichen Standardwerte manuell festlegen." ist am nächsten.

MSDN sagt weiter über DefaultValueAttribute:

A Default wird kein Mitglied verursacht automatisch mit dem Wert des Attributs initialisiert werden. Sie müssen den Anfangswert in Ihrem Code festlegen.

dh Sie noch das Konstruktor Spiel machen müssen, was Sie sagen, ist der Standardwert, so dass Code, der es immer noch funktioniert, wie die in der XML-Serialisierung gebaut vertraut, wird sie zur Arbeit nutzen, ob die Eigenschaft serialise oder nicht; In ähnlicher Weise wird der Formulardesigner die DefaultValue s verwenden, um herauszufinden, welcher Code automatisch generiert werden muss.

1

Von MSDN Hilfe:

AttributeCollection^ attributes = TypeDescriptor::GetProperties(this)[ "MyProperty" ]->Attributes; 

/* Prints the default value by retrieving the DefaultValueAttribute 
     * from the AttributeCollection. */ 
DefaultValueAttribute^ myAttribute = dynamic_cast<DefaultValueAttribute^>(attributes[ DefaultValueAttribute::typeid ]); 
Console::WriteLine("The default value is: {0}", myAttribute->Value); 

Ich brauche den Standardwert Attribut etwas nicht statisch zu setzen. Wie kann ich es im Grunde einstellen, wann immer ich will?


Gelöst durch Überschreiben der ShouldSerialize-Funktionen in der Klasse mit den Eigenschaften.

Beispiel:

property System::String^ Z { 
      System::String^ get(){...} 
      void set(System::String^ value) {...} 
     } 

     bool ShouldSerializeZ() { 
      return Z != <call to run time objects> 
     } 
0

Sie diese Art von Magie mit Aspect Orientiert Frameworks wie Nachlese oder Postsharp passieren kann.

10

diese vier Jahre später zu aktualisieren: Derzeit JSON.net die Einstellung DefaultValueHandling Parameter macht Default den Weg @aaron erwartet funktionieren:

[JsonProperty("allowUploading",DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] 
[DefaultValue(true)] 
public bool AllowUploading { get; set; } 
+0

Nun, das ist definitiv nützlich! – Aaron

8

Sie können tatsächlich „Kraft“ ist es ziemlich leicht für jede Klasse zu arbeiten.

Zuerst müssen Sie Objekterweiterungsmethode im System-Namespace schreiben:

public static class ObjectExtensions 
{ 
    public static void InitializePropertyDefaultValues(this object obj) 
    { 
     PropertyInfo[] props = obj.GetType().GetProperties(); 
     foreach (PropertyInfo prop in props) 
     { 
      var d = prop.GetCustomAttribute<DefaultValueAttribute>(); 
      if (d != null) 
       prop.SetValue(obj, d.Value); 
     } 
    } 
} 

Dann im Konstruktor einer Klasse, die in der Hierarchie der Klassen hoch genug ist, die tatsächlich solche automatische Standardwert Initialisierung müssen Sie muss nur eine Zeile hinzufügen:

public MotherOfMyClasses() 
    { 
     this.InitializePropertyDefaultValues(); 
    } 
+0

Schön. Wenn Sie für jeden _new_-Typ eine statische Liste von 'Action'-Objekten erstellen und diese von' InitializePropertyDefaultValues ​​() 'aufrufen, würde dies die Kosten der Reflektion nur auf einen Zeitpunkt verschieben, wenn die Klasse initialisiert wird. – Suncat2000