Archives

DefaultValue Attribute as Initial Value

Visual Studio Properties

C# lets the programming define a default value on a class property, so that GUI widgets can test the property to see if it still has the default value. Visual Studio, for example, bolds any properties that have a non-default value, making them easy to pick out.

Unfortunately, the default value isn't used to actually initialize the property. The initialization must be done elsewhere in the code, typically in the class's constructor. Having to type the same value in two separate places in the code is error-prone, since it's easy to inadvertently change the value in one place and forget to change it in the other.

System Message: ERROR/3 (<stdin>, line 16)

Unknown directive type "code-block".

.. code-block:: c#

    public class Widget
    {
        [DefaultValue(5)]
        public int WidgetLength { get; set; }

        public Widget()
        {
             WidgetLength = 5;
        }
    }

With only one property in the class, the chances of an error are small. However, when you have dozens of properties and the constructor is hundreds of lines away from the DefaultValue, mismatches are bound to happen. Furthermore, so many people assume that setting the DefaultValue will initialize the property that Microsoft issued a Knowledge Base bulletin to clarify the matter. (Why can't they just make the documentation more explicit?)

Since I hate maintaining error-prone code, I wrote a function that initializes all of an instance's properties using the DefaultValue attributes. I can set the DefaultValue attribute on each property, call the function once in the constructor, and forget about it.

System Message: ERROR/3 (<stdin>, line 38)

Unknown directive type "code-block".

.. code-block:: c#

       static public void ApplyDefaultValues(object self)
       {
            foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(self)) {
                DefaultValueAttribute attr = prop.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
                if (attr == null) continue;
                prop.SetValue(self, attr.Value);
            }
       }
Share

3 comments to DefaultValue Attribute as Initial Value

  • That’s nice, would be cooler if ApplyDefaultValues was an extension method for something like System.Object or the base class of all your implementation-specific classes.

  • Good stuff, but it will also apply default values for the properties of the base class – which you may have modified inside your constructor prior to calling this function… The following is slightly modified code that ignores base class properties:

    public static class DefaultValues
    {
    static public void Apply(object self)
    {
    if (self == null)
    return;

    Type baseType = self.GetType().BaseType;
    PropertyInfo[] baseProps = baseType != null ? baseType.GetProperties() : new PropertyInfo[0];

    foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(self))
    {
    bool skip = false;

    foreach (PropertyInfo info in baseProps)
    if (prop.Name == info.Name)
    {
    skip = true;
    break;
    }

    if (skip)
    continue;

    DefaultValueAttribute attr = prop.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;

    if (attr == null)
    continue;

    prop.SetValue(self, attr.Value);
    }
    }
    }

Leave a Reply