views:

61

answers:

1

I'm trying to write an extension method that I can use to copy values from one object property to another object of a different type, as long as the property names and types match exactly.

This is what I have:

public static T CopyFrom<T>(this T toObject, object fromObject)
    {
        var fromObjectType = fromObject.GetType();
        var fromProperties = fromObjectType.GetProperties();

        foreach (PropertyInfo toProperty in toObject.GetType().GetProperties())
        {
            PropertyInfo fromProperty = fromObjectType.GetProperty(toProperty.Name);

            if (fromProperty != null) // match found
            {
                // check types
                var fromType = fromProperty.PropertyType.UnderlyingSystemType;
                var toType = toProperty.PropertyType.UnderlyingSystemType;

                if (toType.IsAssignableFrom(fromType))
                {
                    toProperty.SetValue(toObject, fromProperty.GetValue(fromObject, null), null);
                }
            }
        }

        return toObject;
    }

This is working great for non boxed types, but Nullable<T> returns false when I call

toType.IsAssignableFrom(fromType)

because its type is Nullable<T> and is not the underlying type T.

I read here that GetType() should unbox the Nullable<T> so it returns T but if I call that on PropertyInfo.PropertyType I get ReflectedMemberInfo and not the type T im looking for.

I think I'm missing something obvious here, so I thought I would throw it open to SO to get some advice.

Anyone have any ideas?

UPDATE: Here is the final method for anyone searching for this.

 public static T CopyFrom<T>(this T toObject, object fromObject)
    {
        var fromObjectType = fromObject.GetType();

        foreach (PropertyInfo toProperty in toObject.GetType().GetProperties())
        {
            PropertyInfo fromProperty = fromObjectType.GetProperty(toProperty.Name);

            if (fromProperty != null) // match found
            {
                // check types
                var fromType = Nullable.GetUnderlyingType(fromProperty.PropertyType) ?? fromProperty.PropertyType;
                var toType = Nullable.GetUnderlyingType(toProperty.PropertyType) ?? toProperty.PropertyType;

                if (toType.IsAssignableFrom(fromType))
                {
                    toProperty.SetValue(toObject, fromProperty.GetValue(fromObject, null), null);
                }
            }
        }

        return toObject;
    }
+2  A: 

You're looking for Nullable.GetUnderlyingType.

For example:

toType = Nullable.GetUnderlyingType(toType) ?? toType;
SLaks
James
No, you don't. `Nullable.GetUnderlyingType` will return `null` if it's not nullable, so my code sample will work for all types.
SLaks
Perfect Cheers.
James