Click here to Skip to main content
15,891,529 members
Articles / Programming Languages / C#
Article

Setting Default Values on Automatic Properties

Rate me:
Please Sign up or sign in to vote.
3.53/5 (8 votes)
14 May 2008CPOL2 min read 95.4K   197   23   36
An article on implementing default values on Automatic Properties

Introduction

C# 3.0 introduces a great new feature called Automatic Properties, and if you haven’t already read about them, I would encourage you to read Scott Guthrie's introductory post.

As great as they are and as much time as they save, Automatic Properties have a serious drawback – you can’t set the default value of the property. Instead, the compiler will initialize value properties to 0, reference properties to null, and enum’s to the first member, and while this might work for some applications, it wasn’t working for mine.

Background

When I thought about the implementation, two options became apparent. One, I could create a base object class and have all of my classes inherit from this base class. This however isn’t a great solution because a number of my classes inherit from other classes outside of my control, and since .NET does not support multiple inheritances, it was clear this wasn’t going to work. To my rescue was the also new C# 3.0 feature, Extension Methods. If you haven’t already heard about Extension Methods, I’d recommend reading another one of Scott Guthrie's blog posts about them.

Using the Code

Using the code requires that you decorate your properties with an attribute already available in the System.ComponentModel namespace – if you haven’t already guessed it, it’s the aptly named DefaultValueAttribute attribute. As well, it requires a quick call to the InitDefaults() extension method from the constructor which I will discuss a bit later.

The attached code supplies a demo implementation of the TestObject and TestObjectInherited classes:

C#
public class TestObject
    {
        public TestObject()
        {
            this.InitDefaults();
        }

        [DefaultValue(-45)]
        public int DefaultInt
        {
            get;
            set;
        }

        [DefaultValue(10.23)]
        public double DefaultDouble
        {
            get;
            set;
        }

        [DefaultValue(true)]
        public bool DefaultBool
        {
            get;
            set;
        }

        [DefaultValue(TestEnum.Value2)]
        public TestEnum DefaultEnum
        {
            get;
            set;
        }

        [DefaultValue("DefaultString!")]
        public string DefaultString
        {
            get;
            set;
        }

        public string StringWithoutDefault
        {
            get;
            set;
        }

        public string ValueOfPrivateProperty
        {
            get
            {
                return PrivateProperty;
            }
        }

        [DefaultValue("This is a private property!")]
        protected string PrivateProperty
        {
            get;
            set;        
        }
    }

The magical InitDefaults() method is implemented as an extension method which uses reflection to set the value of the properties to the default value:

C#
public static void InitDefaults(this object o)
        {
            PropertyInfo[] props = o.GetType().GetProperties(BindingFlags.Public | 
                BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

            for (int i = 0; i < props.Length; i++)
            {
                PropertyInfo prop = props[i];                

                if (prop.GetCustomAttributes(true).Length > 0)
                {
                    object[] defaultValueAttribute = 
                        prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);

                    if (defaultValueAttribute != null)                    
                    {
                        DefaultValueAttribute dva = 
                            defaultValueAttribute[0] as DefaultValueAttribute;
                        
                        if(dva != null)
                            prop.SetValue(o, dva.Value, null);                                
                    }
                }
            }
        }

Points of Interest

I decided to support initializing the default value of properties in inherited classes, but if you don’t want this behavior, you can simply pass false to GetCustomAttributes().

C#
if (prop.GetCustomAttributes(false).Length > 0)
                {
                    object[] defaultValueAttribute = prop.GetCustomAttributes
                        (typeof(DefaultValueAttribute), false);

                    if (defaultValueAttribute != null)                    
                    {
                        DefaultValueAttribute dva = 
                            defaultValueAttribute[0] as DefaultValueAttribute;
                        
                        if(dva != null)
                            prop.SetValue(o, dva.Value, null);                                
                    }
                }

History

  • 14th May, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Canada Canada
Steven is VP Development at MBC Computer Solutions Ltd. (http://www.mbccs.com), a Richmond Hill based company specializing in e-Business Application Development, e-Store Solutions, Managed Co-Location and Proactive IT services.

Steven has over 10 years experience in software and hardware design and is experienced with a large array of platforms, technologies and languages.

In his spare time, Steven enjoys a wide array of music, is an avid skier and enjoys spending time with friends.

Steven is the primary contributor of MBC's blog which can be read at http://blogs.mbccs.com/mbccomputersolutions

Comments and Discussions

 
Questionover-design? Pin
Todd Menier29-Oct-08 9:03
Todd Menier29-Oct-08 9:03 
GeneralDiffent approach Pin
Günther M. FOIDL8-Oct-08 0:01
Günther M. FOIDL8-Oct-08 0:01 
RantVote for initialization to be added as a language feature. Pin
Laughing.John23-Aug-08 13:08
Laughing.John23-Aug-08 13:08 
GeneralI don't think its a good idea Pin
Jorge Bay Gondra22-Aug-08 3:18
Jorge Bay Gondra22-Aug-08 3:18 
GeneralAnother option Pin
Ajek20-May-08 11:02
Ajek20-May-08 11:02 
GeneralRe: Another option Pin
nsimeonov9-Jun-09 16:32
nsimeonov9-Jun-09 16:32 
GeneralA opinion Pin
Ricky Wang19-May-08 19:57
Ricky Wang19-May-08 19:57 
GeneralI'd do it differently... Pin
PIEBALDconsult14-May-08 13:49
mvePIEBALDconsult14-May-08 13:49 
GeneralRe: I'd do it differently... Pin
Seishin#15-May-08 1:56
Seishin#15-May-08 1:56 
GeneralRe: I'd do it differently... Pin
PIEBALDconsult15-May-08 5:56
mvePIEBALDconsult15-May-08 5:56 
GeneralRe: I'd do it differently... Pin
PIEBALDconsult15-May-08 7:39
mvePIEBALDconsult15-May-08 7:39 
GeneralRe: I'd do it differently... Pin
Seishin#15-May-08 8:30
Seishin#15-May-08 8:30 
GeneralRe: I'd do it differently... Pin
PIEBALDconsult15-May-08 9:45
mvePIEBALDconsult15-May-08 9:45 
GeneralRe: I'd do it differently... Pin
Seishin#15-May-08 9:47
Seishin#15-May-08 9:47 
GeneralRe: I'd do it differently... Pin
PIEBALDconsult15-May-08 10:15
mvePIEBALDconsult15-May-08 10:15 
GeneralI Don't See The Value In Automatic Properties Pin
#realJSOP14-May-08 11:26
mve#realJSOP14-May-08 11:26 
GeneralRe: I Don't See The Value In Automatic Properties [modified] Pin
PIEBALDconsult14-May-08 13:16
mvePIEBALDconsult14-May-08 13:16 
GeneralRe: I Don't See The Value In Automatic Properties Pin
William E. Kempf15-May-08 6:47
William E. Kempf15-May-08 6:47 
GeneralRe: I Don't See The Value In Automatic Properties Pin
PIEBALDconsult15-May-08 7:53
mvePIEBALDconsult15-May-08 7:53 
GeneralRe: I Don't See The Value In Automatic Properties Pin
William E. Kempf15-May-08 8:37
William E. Kempf15-May-08 8:37 
GeneralRe: I Don't See The Value In Automatic Properties Pin
PIEBALDconsult15-May-08 9:29
mvePIEBALDconsult15-May-08 9:29 
GeneralRe: I Don't See The Value In Automatic Properties Pin
William E. Kempf15-May-08 9:42
William E. Kempf15-May-08 9:42 
PIEBALDconsult wrote:
Well, my understanding is that extension methods are for when one doesn't have the ability to modify the class/interface. If you do have control over the class/interface, and it makes sense to add the method, then go right ahead and add it; if not, why use an extension method to make it look like you did?


With a class, that's absolutely correct. I explained why it's not ideal with an interface. "Just adding it" to the interface means that every implementation has to provide an implementation that should be THE EXACT SAME implementation in every case.

PIEBALDconsult wrote:
There are two things I don't like about extension methods:
They require a using directive.


So does everything else. In all of the use cases I gave, however, the extension method resides in the SAME namespace, so no extra using is required.

I will give you a partial point (maybe an 1/8 point) here. The IDE automates adding the using most of the time, but with extension methods it can't. This causes me a little grief from time to time with LINQ. It's not the end of the world, however.

PIEBALDconsult wrote:
When the code is printed out or posted online, or otherwise not displayed in VS, I can't tell that a particular method is an extension method.


The classic counter argument, and it holds NO water with me. If I'm reading code, not maintaining it, why would I care? If I'm maintaining, I'm going to be using developer tools that will reveal what I need to know.

PIEBALDconsult wrote:
Oh, and what if they who do control the class/interface later add a method that matches the extension method but does something else? (I'll have to check that out myself.)


The non-extension method will be called.

William E. Kempf

GeneralRe: I Don't See The Value In Automatic Properties Pin
Steven Berkovitz15-May-08 9:44
Steven Berkovitz15-May-08 9:44 
GeneralRe: I Don't See The Value In Automatic Properties Pin
William E. Kempf15-May-08 9:46
William E. Kempf15-May-08 9:46 
GeneralRe: I Don't See The Value In Automatic Properties Pin
PIEBALDconsult15-May-08 9:49
mvePIEBALDconsult15-May-08 9:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.