Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET - Get default value for a reflected PropertyInfo

This is really stumping me today. I'm sure its not that hard, but I have a System.Reflection.PropertyInfo object. I want to set its value based on the result of a database lookup (think ORM, mapping a column back to a property).

My problem is if the DB returned value is DBNull, I just want to set the property value to its default, the same as calling:

value = default(T);  // where T is the type of the property.

However, the default() method won't compile if you give it a Type, which is what I have:

object myObj = ???; // doesn't really matter. some arbitrary class.
PropertyInfo myPropInf = ???; // the reflection data for a property on the myObj object.
myPropInf.SetValue(myObj, default(myPropInf.PropertyType), null);

The above doesn't compile. default(Type) is invalid. I also thought about doing:

object myObj = ???;
PropertyInfo myPropInf = ???;
myPropInf.SetValue(myObj, Activator.CreateInstance(myPropInf.PropertyType), null);

However, if the Type is string, that would assign the value "new String()", but I really want "null", which is what "default(string)" would return.

So what am I missing here? I suppose a really hacky way would be to create a new instance of myObj's Type and copy the property over, but that just seems stupid...

object myObj = ???;
PropertyInfo  myPropInf = ???;
var blank = Activator.CreateInstance(myObj.GetType());
object defaultValue = myPropInf.GetValue(blank, null);
myPropInf.SetValue(myObj, defaultValue, null);

I'd rather not waste the memory to make a whole new instance, just to get the default for the property though. Seems very wasteful.

Any ideas?

like image 304
CodingWithSpike Avatar asked Jan 02 '09 16:01

CodingWithSpike


People also ask

Are property default values implementation specific or type specific?

Property default values are implementation specific, not type specific. They might coincide in many cases but it doesn't have to be so.

How to filter the return value of getproperties ()?

Pass in the BindingFlags parameter to control what GetProperties () looks for. This is an enum flag, so you have to OR the options together. Filter the returned PropertyInfo objects by looking at its properties, such as PropertyInfo.PropertyType.

How do I set the default value to a private property field?

The following example sets the default value to a private property field. You can assign the default value using the DefaultValueAttribute attribute, as shown below. tutorialsteacher.com is a free self-learning technology web site for beginners and professionals.

What is the default value of the parameter?

The default value of the parameter, or Value if the parameter has no default value. This property is used only in the execution context. In the reflection-only context, use the RawDefaultValue property instead.


3 Answers

I believe if you just do

prop.SetValue(obj,null,null);

If it's a valuetype, it'll set it to the default value, if it's a reference type, it'll set it to null.

like image 104
BFree Avatar answered Oct 11 '22 12:10

BFree


object defaultValue = type.IsValueType ? Activator.CreateInstance(type) : null;
like image 22
Darin Dimitrov Avatar answered Oct 11 '22 11:10

Darin Dimitrov


The "null" trick will set it to the zero value for the type, which is not necessarily the same as the default for the property. Firstly, if it is a new object, why not just leave it alone? Alternatively, use TypeDescriptor:

PropertyDescriptor prop = TypeDescriptor.GetProperties(foo)["Bar"];
if (prop.CanResetValue(foo)) prop.ResetValue(foo);

This respects both [DefaultValue] and the Reset{name}() patterns (as used by binding and serialization), making it very versatile and re-usable.

If you are doing lots of this, you can also get a performance boost using TypeDescriptor instead of reflection, by re-using the PropertyDescriptorCollection and using HyperDescriptor (same code, but much faster than either refletion or raw TypeDescriptor).

like image 34
Marc Gravell Avatar answered Oct 11 '22 11:10

Marc Gravell