Метод расширения для копирования свойств объекта формы в другой, с первой попытки - PullRequest
2 голосов
/ 13 мая 2010

Я пытаюсь написать метод расширения, который можно использовать для копирования значений из одного свойства объекта в другой объект другого типа, если имена и типы свойств точно совпадают.

Вот что у меня есть:

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

Это прекрасно работает для не штучных типов, но Nullable<T> возвращает ложь, когда я звоню

toType.IsAssignableFrom(fromType)

потому что его тип Nullable<T> и не является базовым типом T.

Я прочитал здесь , что GetType() должен распаковать Nullable<T>, поэтому он возвращает T, но если я вызову это на PropertyInfo.PropertyType, я получу ReflectedMemberInfo, а не T ищу.

Я думаю, что я упускаю что-то очевидное здесь, поэтому я решил открыть это SO, чтобы получить какой-то совет.

У кого-нибудь есть идеи?

ОБНОВЛЕНИЕ: Вот последний метод для любого, кто ищет это.

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

1 Ответ

2 голосов
/ 13 мая 2010

Вы ищете Nullable.GetUnderlyingType.

Например:

toType = Nullable.GetUnderlyingType(toType) ?? toType;
...