2010-02-24 12 views
43

la gente que he oído decir algunas cosas diferentes sobre el atributo DefaultValue incluyendo:.NET ValorPredeterminado atributo

  • "Se establece el valor de la propiedad antes de que algo más lo usa."
  • "No funciona para autopropiedades".
  • "Solo es para decoración. Debe establecer manualmente los valores predeterminados reales".

¿Cuál (si existe) es correcto? ¿Realmente el DefaultValue establece valores predeterminados? ¿Hay casos en que no funciona? ¿Es mejor simplemente no usarlo?

Respuesta

45

El lugar donde generalmente utilizo DefaultValue es para las clases que se serializan/deserializan a XML. Es no establece el valor predeterminado durante la creación de instancias y no afecta las propiedades automáticas.

De MSDN:

Un DefaultValueAttribute no causará un miembro que ser inicializado de forma automática con el valor del atributo. Debe establecer el valor inicial en su código.

MSDN - DefaultValueAttribute Class


Edit: Como Roland señala, y, como otros han mencionado en sus respuestas al atributo también es usado por el diseñador de la forma

+0

Es bueno saberlo. ¡Gracias! – Aaron

+1

No olvides que el diseñador de formularios también lo usa ... –

1

"Se establece el valor de la propiedad antes cualquier otra cosa lo usa ". -> No, el valor predeterminado es solo para el diseñador. un valor predeterminado no se seralizará en el código del diseñador.

"No funciona para autopropiedades". -> No

"Solo es para decoración. Debe establecer manualmente valores predeterminados reales". -> No. Debido a la Serialización de Diseñador. Pero debes configurarlo manualmente.

11

Al igual que todos los atributos, son metadatos, y como tal "Solo es para decoración. Debe establecer manualmente valores predeterminados reales". está más cerca.

MSDN va a decir acerca DefaultValueAttribute:

Un DefaultValueAttribute no causará un miembro a ser inicializado de forma automática con el valor del atributo. Debe establecer el valor inicial en su código.

es decir, usted todavía tiene que hacer el partido constructor de lo que se dice es el valor por defecto para que el código que confía en que todavía funciona, como el construido en la serialización XML se utilizan para averiguar si a serializar la propiedad o no; de manera similar, el diseñador de formularios usará el DefaultValue para determinar qué código se debe generar automáticamente.

1

De MSDN ayuda:

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); 

necesito para establecer el atributo de valor por defecto a algo no estático. ¿Cómo puedo configurarlo cuando quiero?


que resuelve anulando las funciones ShouldSerialize en la clase de la celebración de las propiedades.

Ejemplo:

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

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

se puede hacer este tipo de magia suceda con los marcos de aspecto Orientada como elemento secundario o PostSharp.

10

actualizar este cuatro años más tarde: En la actualidad, el establecimiento de parámetros de JSON.net DefaultValueHandling hace ValorPredeterminado funciona de la manera esperada @aaron:

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

Bueno, eso definitivamente es útil. – Aaron

8

En realidad se puede "forzar" a trabajar en cualquier clase con bastante facilidad.

primer lugar usted necesita para escribir el método de extensión objeto en el espacio de nombres System:

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

A continuación, en el constructor de una clase que es lo suficientemente alto en la jerarquía de clases que realmente necesitan ese valor por defecto de auto inicialización se solo necesita agregar una línea:

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

Agradable. Si crea una lista estática de objetos 'Action' para cada _new_tynd invoke de' InitializePropertyDefaultValues ​​() ', esto cambiaría el costo de la reflexión a una sola vez cuando la clase se inicializa. – Suncat2000

Cuestiones relacionadas