C#.NET中不同类型对象的深拷贝方法我需要通过字段名映射ObjectV1和ObjectV2之间的所有字段值和子类收集。ObjectV2和ObjectV1位于不同的命名空间中。模板ClassV1和ClassV2之间的继承已打折,因为这两个类需要独立发展。我考虑过使用反射(慢)和二进制序列化(也慢)来执行公共属性的映射。有首选方法吗?还有其他选择吗?作为每次都使用反射的替代方法,您可以创建一个使用Reflection.Emit的辅助类来动态创建复制方法——这意味着您只能在启动时获得性能。这可以为您提供所需的灵活性和性能组合。由于Reflection.Emit非常笨重,我建议查看Reflector插件,它非常适合构建此类代码。这是什么版本的.NET?对于浅拷贝:在3.5中,您可以预编译Expression来执行此操作。在2.0中,您可以非常轻松地使用HyperDescriptor来执行相同的操作。两者都将远远超过反思。在MiscUtil中有一个预先实现的表达式方法-PropertyCopy:DestTypeclone=PropertyCopy.CopyFrom(original);(浅)BinaryFormatter(在问题中)不是一个选项-它根本不起作用,因为原始类型和目标类型不同。如果数据是基于契约的,那么如果所有契约名称都匹配,则XmlSerializer或DataContractSerializer将起作用,但如果可能,上面的两个(浅)选项会更快。此外-如果您的类型标有通用序列化属性(XmlType或DataContract),那么protobuf-net可以(在某些情况下)为您执行深度复制/更改类型:DestTypeclone=Serializer.ChangeType(original);但是取决于具有非常相似模式的类型(实际上,它不使用名称,它在属性上使用显式“顺序”等)。您可能想看看AutoMapper,这是一个专门用于复制值的库物体之间。它使用约定优于配置,因此如果该属性确实与exaxt同名,它几乎可以为您完成所有工作。这是我建立的解决方案://////将一个对象的数据复制到另一个对象。目标对象获取第一个对象的属性。///任何匹配的属性(按名称)被写入目标。//////要从中复制的源对象///要复制到的目标对象);}//////将一个对象的数据复制到另一个对象。目标对象获取第一个对象的属性。///任何匹配的属性(按名称)被写入目标。//////要从中复制的源对象///要复制到的目标对象///不应复制的逗号分隔属性列表///反射绑定访问publicstaticvoidCopyObjectData(objectsource,objecttarget,stringexcludedProperties,BindingFlagsmemberAccess){string[]excluded=null;}如果(!string.IsNullOrEmpty(excludedProperties)){excluded=excludedProperties.Split(newchar[1]{','},StringSplitOptions.RemoveEmptyEntries);}MemberInfo[]miT=target.GetType().GetMembers(memberAccess);foreach(miT中的MemberInfo字段){stringname=Field.Name;//跳过排除的属性if(string.IsNullOrEmpty(excludedProperties)==false&&excluded.Contains(name)){continue;}if(Field.MemberType==MemberTypes.Field){FieldInfosourcefield=source.GetType().GetField(name);如果(源字段==null){继续;}objectSourceValue=sourcefield.GetValue(source);((FieldInfo)Field).SetValue(target,SourceValue);}elseif(Field.MemberType==MemberTypes.Property){PropertyInfopiTarget=FieldasPropertyInfo;PropertyInfosourceField=source.GetType().GetProperty(name,memberAccess);如果(sourceField==null){继续;}if(piTarget.CanWrite&&sourceField.CanRead){objecttargetValue=piTarget.GetValue(target,null);对象sourceValue=sourceField.GetValue(source,null);如果(sourceValue==null){继续;}if(sourceField.PropertyType.IsArray&&piTarget.PropertyType.IsArray&&sourceValue!=null){CopyArray(source,target,memberAccess,piTarget,sourceField,sourceValue);}else{CopySingleData(源、目标、memberAccess、piTarget、sourceField、targetValue、sourceValue);}}}}}privatestaticvoidCopySingleData(objectsource,objecttarget,BindingFlagsmemberAccess,PropertyInfopiTarget,PropertyInfosourceField,objecttargetValue,objectsourceValue){//如果需要的话实例化目标if(targetValue==null&&piTarget.PropertyType.IsValueType==false&&piTarget.PropertyType!=typeof(string)){if(piTarget.PropertyType.IsArray){targetValue=Activator.CreateInstance(piTarget.PropertyType.GetElementType());}else{targetValue=Activator.CreateInstance(piTarget.PropertyType);}}if(piTarget.PropertyType.IsValueType==false&&piTarget.PropertyType!=typeof(string)){CopyObjectData(sourceValue,targetValue,"",memberAccess);piTarget.SetValue(target,targetValue,null);}else{if(piTarget.PropertyType.FullName==sourceField.PropertyType.FullName){objecttempSourceValue=sourceField.GetValue(source,null);piTarget.SetValue(target,tempSourceValue,null);}else{CopyObjectData(piTarget,target,"",memberAccess);}}}privatestaticvoidCopyArray(objectsource,objecttarget,BindingFlagsmemberAccess,PropertyInfopiTarget,PropertyInfosourceField,objectsourceValue){intsourceLength=(int)sourceValue.GetType().InvokeMember("长度",BindingFlags.GetProperty,null,源值,空);数组targetArray=Array.CreateInstance(piTarget.PropertyType.GetElementType(),sourceLength);数组array=(Array)sourceField.GetValue(source,null);for(inti=0;i如果速度是个问题,您可以使反射过程脱机并生成通用的属性代码,您可以使用轻量级代码生成在运行时编译或通过构建C#代码完全脱机。如果您控制目标对象的实例化,试试JavaScriptSerializer。它不会吐出任何类型的信息。newJavaScriptSerializer().Serialize(newNamespaceA.Person{Id=1,Name="A"})返回{Id:1,Name:"A"}从这里可以反序列化任何具有相同属性名称的类。如果速度是个问题,您应该在方法本身中实现克隆方法。以上就是C#学习教程:如何深度复制C#.NET中不同类型对象共享的所有内容。如果对大家有用,需要了解更多C#学习教程,希望大家多多关注---本文来自网络收藏,不代表立场,如涉及侵权,请右击联系管理员删除。如需转载请注明出处:
