Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set property Nullable<> by reflection

I try to set a Nullable<> property dynamicly.

I Get my property ex :

PropertyInfo property = class.GetProperty("PropertyName"); // My property is Nullable<> at this time So the type could be a string or int

I want to set my property by reflection like

property.SetValue(class,"1256",null);

It's not working when my property is a Nullable<> Generic. So i try to find a way to set my property.

To know the type of my nullable<> property i execute

Nullable.GetUnderlyingType(property.PropertyType)

Any idea ?

  • I Try to create an instance of my Nullable<> property with

    var nullVar = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(new Type[] { Nullable.GetUnderlyingType(property.PropertyType) }));

But nullVar is always Null

like image 528
Cédric Boivin Avatar asked Sep 28 '09 18:09

Cédric Boivin


People also ask

How do you declare a property as Nullable?

You can declare nullable types using Nullable<t> where T is a type. Nullable<int> i = null; A nullable type can represent the correct range of values for its underlying value type, plus an additional null value. For example, Nullable<int> can be assigned any value from -2147483648 to 2147483647, or a null value.

How does reflection set property value?

To set property values via Reflection, you must use the Type. GetProperty() method, then invoke the PropertyInfo. SetValue() method. The default overload that we used accepts the object in which to set the property value, the value itself, and an object array, which in our example is null.

What is nullable property in C#?

Nullable<T>. HasValue indicates whether an instance of a nullable value type has a value of its underlying type. Nullable<T>. Value gets the value of an underlying type if HasValue is true . If HasValue is false , the Value property throws an InvalidOperationException.

How do I set property value?

To set the value of an indexed property, call the SetValue(Object, Object, Object[]) overload. If the property type of this PropertyInfo object is a value type and value is null , the property will be set to the default value for that type.


2 Answers

I hit this same problem as well as an issue with Convert.ChangeType not handling DateTimes on Nullables so I combined a couple of stackoverflow solutions with some .NET 4 dynamic magic to get something I think is kind of sweet. If you look at the code, we use dynamic to type the object to Nullable at run time, then the run time treats it differently and allows assignments of the base type to the nullable object.

public void GenericMapField(object targetObj, string fieldName, object fieldValue)
{
    PropertyInfo prop = targetObj.GetType().GetProperty(fieldName);
    if (prop != null)
    {
        if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            dynamic objValue = System.Activator.CreateInstance(prop.PropertyType);
            objValue = fieldValue;
            prop.SetValue(targetObj, (object)objValue, null);
        }
        else
        {
            prop.SetValue(targetObj, fieldValue, null);
        }
    }
}
like image 94
AdamCrawford Avatar answered Sep 22 '22 13:09

AdamCrawford


public static void SetValue(object target, string propertyName, object value)
{
  if (target == null)
    return;

  PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName);

  object convertedValue = value;
  if (value != null && value.GetType() != propertyInfo.PropertyType)
  {
    Type propertyType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
    convertedValue = Convert.ChangeType(value, propertyType);
  }

  propertyInfo.SetValue(target, convertedValue, null);
}
like image 36
czlatea Avatar answered Sep 18 '22 13:09

czlatea