custom - property c# get set
Atributo de valor predeterminado de.NET (8)
He escuchado a personas decir algunas cosas diferentes sobre el atributo DefaultValue
incluyen:
- "Establece el valor de la propiedad antes de que cualquier otra cosa la use".
- "No funciona para autopropiedades".
- "Es solo para decoración. Debe establecer manualmente los valores predeterminados reales".
¿Cuál (si alguno) es correcto? ¿ DefaultValue
realmente establece valores predeterminados? ¿Hay casos donde no funciona? ¿Es mejor no usarlo?
"Establece el valor de la propiedad antes de que cualquier otra cosa la use". -> No, el valor predeterminado es solo para el diseñador. un valor predeterminado no se serializará en el código del diseñador.
"No funciona para autopropiedades". -> No
"Es solo para decoración. Debe establecer manualmente los valores predeterminados reales". -> No. Debido a la serialización del diseñador. Pero debes configurarlo manualmente.
Al igual que todos los atributos, son metadatos y, como tal, "es solo para decoración. Debe establecer manualmente los valores predeterminados reales". es el mas cercano
MSDN continúa diciendo sobre DefaultValueAttribute :
Un DefaultValueAttribute no hará que un miembro se inicialice automáticamente con el valor del atributo. Debe establecer el valor inicial en su código.
es decir, aún debe hacer que el constructor coincida con lo que dice que es el valor predeterminado, de modo que el código que confía en que todavía funciona, como la serialización XML integrada, los usará para determinar si se debe serializar la propiedad o no; de manera similar, el diseñador de formularios utilizará los DefaultValue
para determinar qué código se debe generar automáticamente.
Desde la ayuda de MSDN :
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 establecer el atributo de valor predeterminado en algo no estático. ¿Cómo puedo configurarlo básicamente cuando quiero?
Resuelto al anular las funciones ShouldSerialize en la clase que contiene las propiedades.
Ejemplo:
property System::String^ Z {
System::String^ get(){...}
void set(System::String^ value) {...}
}
bool ShouldSerializeZ() {
return Z != <call to run time objects>
}
El lugar donde normalmente usé DefaultValue
es para las clases que están serializadas / deserializadas a XML. No establece el valor predeterminado durante la creación de instancias y no afecta a las propiedades automáticas.
Desde MSDN:
Un DefaultValueAttribute no hará que un miembro se inicialice automáticamente con el valor del atributo. Debe establecer el valor inicial en su código.
MSDN - DefaultValueAttribute Class
Edición: como señala Roland, y como otros mencionaron en sus respuestas, el diseñador de formularios también utiliza el atributo.
En las últimas versiones de C#
, puedes hacer:
public class InitParam
{
public const int MyInt_Default = 32;
public const bool MyBool_Default = true;
[DefaultValue(MyInt_Default)]
public int MyInt{ get; set; } = MyInt_Default;
[DefaultValue(MyBool_Default)]
public bool MyBool{ get; set; } = MyBool_Default;
}
Para actualizar esto cuatro años más tarde: actualmente, al configurar el parámetro DefaultValueHandling de DefaultValueHandling , DefaultValue funciona de la manera que @aaron esperaba:
[JsonProperty("allowUploading",DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
[DefaultValue(true)]
public bool AllowUploading { get; set; }
Realmente puedes "forzarlo" para que funcione en cualquier clase con bastante facilidad.
Primero necesitas escribir el método de extensión de objeto en el espacio de nombres del sistema:
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);
}
}
}
Luego, en el constructor de una clase que es lo suficientemente alta en la jerarquía de sus clases que realmente necesitan tal inicialización automática de valores por defecto, solo necesita agregar una línea:
public MotherOfMyClasses()
{
this.InitializePropertyDefaultValues();
}
puede hacer que este tipo de magia suceda con marcos orientados a aspectos como Afterthought o Postsharp.