57

I've heard people say a few different things about the DefaultValue attribute including:

  • "It sets the value of the property before anything else uses it."
  • "It doesn't work for autoproperties."
  • "It's only for decoration. You must manually set actual default values."

Which (if any) is right? Does DefaultValue actually set default values? Are there cases where it doesn't work? Is it best just not to use it?

8 Answers 8

58

The place where I typically used DefaultValue is for classes which are serialized/deserialized to XML. It does not set the default value during instantiation and doesn't impact autoproperties.

From MSDN:

A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.

MSDN - DefaultValueAttribute Class


Edit: As Roland points out, and as others mentioned in their answers the attribute is also used by the Form Designer

Sign up to request clarification or add additional context in comments.

Comments

22

To update this four years later: Currently, setting JSON.net's DefaultValueHandling parameter makes DefaultValue work the way @aaron expected:

[JsonProperty("allowUploading",DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] [DefaultValue(true)] public bool AllowUploading { get; set; } 

Comments

15

Like all attributes, it's meta data, and as such "It's only for decoration. You must manually set actual default values." is closest.

MSDN goes on to say about DefaultValueAttribute:

A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.

i.e. You still need to make the constructor match what you say is the default value so that code that trusts it still works, such as the built in XML Serialization will use them to work out whether to serialise the property or not; similarly the form designer will use the DefaultValues to work out what code needs to be automatically generated.

Comments

14

You actually can "force" it to work on any class pretty easily.

First you need to write object extension method in the System namespace:

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); } } } 

Then in the constructor of a class which is high enough in the hierarchy of your classes that actually need such auto default value initialization you just need to add one line:

 public MotherOfMyClasses() { this.InitializePropertyDefaultValues(); } 

1 Comment

Nice. If you create a static list of Action objects for each new type and invoke them from InitializePropertyDefaultValues(), this would shift the cost of reflection to one time only when the class is initialized.
5

In the latest versions of C#, you can do:

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; } 

2 Comments

Everyone should be aware that this method only works for auto-implemented properties. If you've got any sort of custom code in your get and set methods, you can't do this.
If you don't have an auto implemented property, you'll have an explicit backing field so you can set it there.
2

"It sets the value of the property before anything else uses it." --> No the default value is only for the designer. a default value will not be seralized into the designer code.

"It doesn't work for autoproperties." --> No

"It's only for decoration. You must manually set actual default values." --> No. Because of the Designer Serialization. But you must set it manually.

Comments

1

From MSDN help:

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 ); 

I need to set the default value attribute to something non static. How can I basically set it whenever I want to?


Solved by overriding the ShouldSerialize functions in the class holding the properties.

Example:

property System::String^ Z { System::String^ get(){...} void set(System::String^ value) {...} } bool ShouldSerializeZ() { return Z != <call to run time objects> } 

Comments

0

you can make this kind of magic happen with Aspect Orientated Frameworks like Afterthought or Postsharp.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.