Is it possible to assign the default value of a property with an attribute?

Asked

Viewed 3,847 times

3

I wish I could declare a property as:

[DefaultValue(10)]
public int Maximo { get; set; }

And when I was going to use it, it already came with the value started in 10. However the attribute does not assign the value when I try to use:

public void FazAlgo()
{
    int max = Maximo; // 0
}

The value comes 0, which is the pattern of the integer.

An alternative would be to create a field and implement the get and set, but I’m looking for a way to do this without the need to implement the methods.

Would you like to do with attributes in the way I exemplified, is it possible? Like?

2 answers

3


The attribute DefaultValue, as stated in the specification, by itself does not change the value of the property. It serves to be used by the design editor and code generators.

It is possible to use Reflection (note that Reflection has/(may have) a performance cost, is not recommended to replace trivial assignments) to start the properties, the following extension method obtains all class properties and checks by attribute DefaultValue, if you find it get the value of the attribute and assign the property.

public static class Extensoes
{
    // método de extensão para `Object`, funcionando assim em
    // todas classes
    public static void InicializaValores(this Object o)
    {
        // obtem todas propriedades, campos...
        var propriedades = o.GetType()
            .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

        // para cada propriedade
        foreach (var propriedade in propriedades)
        {
            // pega o atributo DefaultValue
            var atributos = propriedade
                .GetCustomAttributes(typeof(DefaultValueAttribute), true)
                .OfType<DefaultValueAttribute>().ToArray();

            // se encontrou
            if (atributos != null && atributos.Length > 0)
            {
                // pega o atributo
                var atributoValorPadrao = atributos[0];

                // seta o valor da propriedade do objeto o
                // para o valor do atributo
                propriedade.SetValue(o, atributoValorPadrao.Value, null);
            }
        }
    }
}

With this method to read the value of attributes and associate with the property, it is still necessary to invoke the method.

This can be done in the class constructor, for example:

public class Teste
{
    [DefaultValue(10)]
    public int Maximo { get; set; }

    public int Minimo { get; set; }

    public Teste()
    {
        this.InicializaValores();
    }
}

Testing:

static class Program
{
    static void Main(string[] args)
    {
        var test = new Teste();

        // poderia ser feito aqui também
        //test.InicializaValores();

        Console.WriteLine(test.Maximo); // 10
        Console.WriteLine(test.Minimo); // 0

        Console.ReadKey();
    }
}
  • 4

    Out of curiosity, when is this useful? In general terms this replaces a simple work that would be done in the constructor for a much more complex and worse performance. The only advantage I see at first is that the default value is next to the property, but just so it wouldn’t be worth it.

  • Yes, Reflection has its cost. As said at the top, this can be used to design Editors, instead of calling in the constructor would call the method that would initiate the values of the control to put it on the screen.

1

public int Maximo { get; set; } = 10 
// Somente na versão do .NET mais nova, não sei qual exatamente

or, ugly but simplistic:

public bool _maximoFoiAlterado;
public int _maximo;
public int Maximo 
{ 
get
{
    if (!_maximoFoiAlterado) return 10;
    else return _maximo;
}
set
{
    _maximoFoiAlterado = true;
    _maximo = value;
}
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.