public T DeepCopy<T>(T objectToCopy)
{
var objectSerialized = JsonConvert.SerializeObject(objectToCopy);
return JsonConvert.DeserializeObject<T>(objectSerialized);
}
/// <summary>
/// Copies matching object's properties from different type objects i.e from source object to destination Type T object
/// </summary>
/// <param name="source"></param>
/// <returns>New Type T object with copied property values</returns>
public static T CopyPropertiesTo<T>(this object source) where T: new()
{
var fromProperties = source.GetType().GetProperties();
var destination = new T();
var toProperties = destination.GetType().GetProperties();
foreach (var fromProperty in fromProperties)
{
var fromPropertyType = fromProperty.PropertyType;
if (Nullable.GetUnderlyingType(fromPropertyType) != null)
{
fromPropertyType = Nullable.GetUnderlyingType(fromPropertyType);
}
var toProperty = toProperties.FirstOrDefault(x => x.Name.Equals(fromProperty.Name, StringComparison.OrdinalIgnoreCase));
if (toProperty != null)
{
var toPropertyType = toProperty.PropertyType;
if (Nullable.GetUnderlyingType(toPropertyType) != null)
{
toPropertyType = Nullable.GetUnderlyingType(toPropertyType);
}
if (fromPropertyType == toPropertyType)
{
toProperty.SetValue(destination, fromProperty.GetValue(source));
}
}
}
return destination;
}
9条答案
按热度按时间ct3nt3jp1#
作为每次都使用反射的替代方案,您可以创建一个helper类,它使用Reflection.Emit动态创建复制方法-这意味着您只能在启动时获得性能。这可以为您提供所需的灵活性和性能的组合。
由于Reflection.Emit相当笨重,我建议检查this Reflector插件,它非常适合构建这类代码。
tzxcd3kk2#
.NET是什么版本?
浅拷贝:
在Python 3.5中,你可以预编译一个
Expression
来完成这个任务。在Python 2.0中,您可以非常容易地使用HyperDescriptor
来完成同样的操作。两者都将大大超过反射。在
MiscUtil
-PropertyCopy
中有一个Expression
方法的预封装实现:(末端浅)
BinaryFormatter(在问题中)在这里不是一个选项-它根本不起作用,因为原始类型和目标类型是不同的。如果数据是基于合约的,那么XmlSerializer或DataContractSerializer将工作**如果 * 所有合约名称都匹配,但是上面的两个(浅)选项如果可能的话会更快。
另外,如果你的类型被标记为通用序列化属性(
XmlType
或DataContract
),那么protobuf-net可以(在某些情况下)为你执行深度复制/更改类型:但这取决于具有非常相似模式的类型(实际上,它不使用名称,而是在属性上使用显式的“Order”等)
7vux5j2d3#
您可能想看看AutoMapper,这是一个专门用于在对象之间复制值的库。它使用约定而不是配置,所以如果属性真的具有相同的exaxt名称,它将为您完成几乎所有的工作。
vpfxa7rd4#
下面是我构建的一个解决方案:
jtw3ybtb5#
如果速度是一个问题,您可以将反射过程脱机,并为公共属性的Map生成代码。您可以在运行时使用轻量级代码生成来完成此操作,或者通过构建C#代码来完成编译。
pkbketx96#
如果您控制目标对象的示例化,请尝试使用JavaScriptSerializer。它不输出任何类型信息。
退货
由此,应该可以反序列化具有相同属性名的任何类。
f0ofjuux7#
如果速度是一个问题,那么应该在方法本身中实现clone方法。
ddrv8njm8#
对于深度副本,我使用了Newtonsoft和create以及通用方法,例如:
我知道这不是什么正统的解决方案,但它对我很有效。
7uzetpgm9#