Thursday, September 18, 2008 12:25 PM djsolid

Set default value for Properties

Many times I needed to set a default value for a property.

For example at the property below

public string Property1 {get; set;}

I wanted a default value "Value1". The only way was to create a private field or to set it in code like Property1 = "Value1" somewhere.

What if I wanted to do this for all my properties ?

For this case i decided to create a custom attribute which does that thing. Takes a value and if the value of the current property is null sets it to the given value.

 

To be more specific let's begin with the custom attribute class:

 [global::System.AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
sealed class DefaultValueAttribute : Attribute
{
readonly object defaultValue;
readonly Type valueType;

public DefaultValueAttribute(object defaultValue, Type valueType)
{
this.valueType = valueType;
this.defaultValue = Convert.ChangeType(defaultValue, valueType);
}
public Type ValueType { get { return valueType; } }
public object DefaultValue
{
get { return defaultValue; }
}
}

Then we have a helper class with an extension method :

public static class DefaultValueAttributeHelper
{
public static void SetDefaultValues(this object obj)
{
Type t = obj.GetType();
foreach (var item in t.GetProperties())
{
foreach (var attr in item.GetCustomAttributes(typeof(DefaultValueAttribute), true))
{
DefaultValueAttribute val = ((DefaultValueAttribute)attr);
if (item.GetValue(obj, null) == null ||
((item.GetValue(obj, null).ToString() == "0") &&
(val.ValueType != typeof(string))))
item.SetValue(obj, val.DefaultValue, null);
}
}

}
}

And finally how this can be used  for example at an ASP.NET Page:

 

public partial class UserDetails : System.Web.UI.Page
{
public UserDetails()
{
this.SetDefaultValues();
}
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(StringProp + "<br>" + IntProp + "<br>" + (DoubleProp + 1));
}

[DefaultValueAttribute("6.11354", typeof(double))]
public double DoubleProp { get; set; }

[DefaultValueAttribute("6", typeof(int))]
public int IntProp { get; set; }

[DefaultValueAttribute("String1", typeof(string))]
public string StringProp { get; set; }


}

Well that's all ... This is really simple. Next step is to create an interface so the above attirbute can be used with custom objects.

If anyone has any improvements please let me know!

kick it on DotNetKicks.com

Filed under: , , , , ,

Comments

# Set default values for properties

Thursday, September 18, 2008 5:29 AM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# funny wallpaper &raquo; set default value for properties

Thursday, September 18, 2008 5:33 AM by funny wallpaper » set default value for properties

Pingback from  funny wallpaper &raquo; set default value for properties

# re: Set default value for Properties

Thursday, September 18, 2008 6:49 AM by Elven Soft

in the future, post also vb.net version, if possible :)

# re: Set default value for Properties

Thursday, September 18, 2008 7:22 AM by Stefan

Cool solution, but what is wrong with this:

public UserDetails()

       {

           // Set defaults.

           this.DoubleProp = 6.3;

           this.IntProp = 6;

           this.StringProp = "String1";

       }

In all honestly in my opinion sometimes the simple solution is the way to goto, although the attribute solution is quite cool I just think setting in constructor would get the desired effect without the trickery.

My 2 c :)

Stefan

# re: Set default value for Properties

Thursday, September 18, 2008 7:49 AM by djsolid

@Stefan :

There is ABSOLUTELY nothing wrong with that. It is a simpler and better solution and i couldn't agree more with you.

The above is just an alternative and i think it is more discrit in 3000 lines of code you because when you look at the property you know the default value right away.

But again i couldn't agree more with you!

John

# re: Set default value for Properties

Thursday, September 18, 2008 7:49 AM by Will

I agree with Stefan. Your "clever" solution introduces A LOT of code for something that is wicked simple. More code == more potential for bugs. It also equates to less time writing code to actually make you app do what it is supposed to do.

# re: Set default value for Properties

Thursday, September 18, 2008 8:37 AM by Bertkid

I agree that putting the "default value" near the property declaration is MUCH more expressive than hiding it in a constructor.

I didn't even think ASP.NET pages had a constructor.  Obviously they do, but I never see it used by anyone.

Do the ones who don't like this make large ASP.NET apps + pages?  I have a solution similar to this, but its not nearly as elegant, since most of my page-level properties are backed to viewstate (instead of an auto-property).  Since code is often collapsed, that "default value" is not visible.  I'm definitely going to take this technique and try and use it with my viewstate backed properties (so the default value is not hidden in collapsed code in outline mode).

# re: Set default value for Properties

Thursday, September 18, 2008 8:50 AM by Bertkid

Unfortunately upon experimentation, I can't use this technique;  since I don't actually want to "set" the default value into viewstate, but only return it in the getter, and the default value is often used, I fear it will be a perf hit since it would have to look up the attribute's value so often.

# re: Set default value for Properties

Thursday, September 18, 2008 10:17 AM by djsolid

@Bertkid

What exactly are you trying to achive? I made something but i am not quite sure what you mean. Could you please be more specific?

# re: Set default value for Properties

Thursday, September 18, 2008 11:29 AM by retrard

Doesnt the System.ComponentModel.DefaultValue attribute achieve the same thing you are doing?  Why are you trying to rewrite functionality that comes out of the box?

# re: Set default value for Properties

Thursday, September 18, 2008 1:13 PM by AndrewSeven

I would rather just set the values in the constructor, its clear, its explicit, you don't need to resolve the type and its checked at build time.

I do agree that the automatic properties are not very useful when you need a default. When I need a default value, I use a backing variable.

The DefaultValue Attribute only provides a hint to tools, telling them what the expected default value is.

# re: Set default value for Properties

Thursday, September 18, 2008 7:46 PM by Rory Primrose

I really like this idea, but I have to agree with the other commentors. Simple assignments in the constructor is a better solution. My main reasons for this are:

- People expect default assignments in the constructor

- The reflection being used is slower than a constructor assignment

   - On a side note, foreach is slower than for statements

- The attribute uses object as the type of the value passed to the attribute so you will encounter boxing and unboxing of the value

I still like the solution though...

# re: Set default value for Properties

Friday, September 19, 2008 10:53 AM by ZamesCurran

If you move the Convert.ChangeType() call into SetDefaultValues() and use t.PropertyType there, you can eliminate ValueType entirely.  (actually, since it's going from an object to an object, I don't think you need the ChangeType at all)

You can also pass the default value itself as it's native type:

[DefaultValueAttribute(6)]

public int IntProp { get; set; }

[DefaultValueAttribute("String1")]

public string StringProp { get; set; }

# re: Set default value for Properties

Sunday, September 21, 2008 3:57 AM by DigiMortal

IMHO it is not very good idea to hardcode default values. At least you should't hardcode the defaults that may change.

Using attributes may be the best solution if you keep default values in application config and with attributes you are saying the name of the key of default value that corresponds to property.

Something like this:

[DefaultValueAttribute("IncomeTaxRate")]

public decimal IncomeTaxRate { get; set; }

# Weekly Links #19 | GrantPalin.com

Monday, September 22, 2008 12:05 AM by Weekly Links #19 | GrantPalin.com

Pingback from  Weekly Links #19 | GrantPalin.com

Leave a Comment

(required) 
(required) 
(optional)
(required)