将值从一个对象复制到另一个对象(不同类型)

我需要将一个对象的一些属性复制到另一个对象。 但是,某些属性需要从decimal到int的类型转换。

我发现这个问题非常有用: 将值从一个对象复制到另一个对象

但是,我无法弄清楚如何修改Jon Skeet和Marc Gravell的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<Func>(initializer, sourceParameter).Compile(); } } } } 

如果你有

 public class Foo { public decimal Value { get; set; } } public class Bar { public int Value { get; set; } } 

然后使用AutoMapper (可从NuGet获得),您可以将对象Foo映射到对象Bar,如下所示:

 Mapper.CreateMap(); Foo foo = new Foo() { Value = 10.5M }; var bar = Mapper.Map(foo); // bar.Value = 10; 

我们可以使用System.Reflection。 遵循此function:

  public static T CloneData(object source) { var target = (T)Activator.CreateInstance(typeof(T)); Type objTypeBase = source.GetType(); Type objTypeTarget = target.GetType(); PropertyInfo _propinfo = null; var propInfos = objTypeBase.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var propInfo in propInfos) { try { _propinfo = objTypeTarget.GetProperty(propInfo.Name, BindingFlags.Instance | BindingFlags.Public); if (_propinfo != null) { _propinfo.SetValue(target, propInfo.GetValue(source)); } } catch (ArgumentException aex) { if (!string.IsNullOrEmpty(aex.Message)) continue; } catch (Exception ex) { if (!string.IsNullOrEmpty(ex.Message)) return default(T); } } return target; } 

假设我们有两个类:

 public class A { public string Prop1 {get ; set; } public string Prop2 {get ; set; } public string Prop3 {get ; set; } public string Prop4 {get ; set; } } public class B { public string Prop2 {get ; set; } public string Prop3 {get ; set; } } 

我们写道:

 var a = new A { Prop1 = "A", Prop2 = "B", Prop3 = "C", Prop4 = "D", }; var b = CloneData(a); 

我们将得到一个B类实例,其中从A复制Prop2和Prop3值。

你可以查看类似的类型

  int x = 4; if(x.GetType()== typeof(int)) { ///DO Stuff } if(x.GetType()==typeof(decimal) { ///Do stuff }