Копировать значения из одного объекта в другой (другой тип)
Мне нужно скопировать некоторые свойства одного объекта другому. Однако для некоторых свойств требуется преобразование типа из десятичного в int.I '
Мы нашли этот вопрос очень полезным:Копировать значения из одного объекта в другой
Тем не менее, я могуне могу понять, как изменить код в Jon Skeet и Marc Gravell 's MiscUtil для проверки типов свойств и, если источник является десятичным, а цель - int, вызвать Convert.ToIn32 ().
Вот код из MiscUtil, который яЯ хотел бы выяснить, как изменить:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace MiscUtil.Reflection
{
///
/// Generic class which copies to its target type from a source
/// type specified in the Copy method. The types are specified
/// separately to take advantage of type inference on generic
/// method arguments.
///
public static class PropertyCopy where TTarget : class, new()
{
///
/// Copies all readable properties from the source to a new instance
/// of TTarget.
///
public static TTarget CopyFrom(TSource source) where TSource : class
{
return PropertyCopier.Copy(source);
}
///
/// Static class to efficiently store the compiled delegate which can
/// do the copying. We need a bit of work to ensure that exceptions are
/// appropriately propagated, as the exception is generated at type initialization
/// time, but we wish it to be thrown as an ArgumentException.
///
private static class PropertyCopier where TSource : class
{
private static readonly Func copier;
private static readonly Exception initializationException;
internal static TTarget Copy(TSource source)
{
if (initializationException != null)
{
throw initializationException;
}
if (source == null)
{
throw new ArgumentNullException("source");
}
return copier(source);
}
static PropertyCopier()
{
try
{
copier = BuildCopier();
initializationException = null;
}
catch (Exception e)
{
copier = null;
initializationException = e;
}
}
private static Func BuildCopier()
{
ParameterExpression sourceParameter = Expression.Parameter(typeof(TSource), "source");
var bindings = new List();
foreach (PropertyInfo sourceProperty in typeof(TSource).GetProperties())
{
if (!sourceProperty.CanRead)
{
continue;
}
PropertyInfo targetProperty = typeof(TTarget).GetProperty(sourceProperty.Name);
if (targetProperty == null)
{
throw new ArgumentException("Property " + sourceProperty.Name + " is not present and accessible in " + typeof(TTarget).FullName);
}
if (!targetProperty.CanWrite)
{
throw new ArgumentException("Property " + sourceProperty.Name + " is not writable in " + typeof(TTarget).FullName);
}
if (!targetProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
{
throw new ArgumentException("Property " + sourceProperty.Name + " has an incompatible type in " + typeof(TTarget).FullName);
}
bindings.Add(Expression.Bind(targetProperty, Expression.Property(sourceParameter, sourceProperty)));
}
Expression initializer = Expression.MemberInit(Expression.New(typeof(TTarget)), bindings);
return Expression.Lambda(initializer, sourceParameter).Compile();
}
}
}
}