Я пытаюсь написать метод расширения, который можно использовать для копирования значений из одного свойства объекта в другой объект другого типа, если имена и типы свойств точно совпадают.
Вот что у меня есть:
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;
}