Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#对象的深度副本_C#_Deep Copy - Fatal编程技术网

C#对象的深度副本

C#对象的深度副本,c#,deep-copy,C#,Deep Copy,我正在编写一些用C语言编写的代码。在此应用程序中,我有一个自定义集合,定义如下: public class ResultList<T> : IEnumerable<T> { public List<T> Results { get; set; } public decimal CenterLatitude { get; set; } public decimal CenterLongitude { get; set; } } 如何执行已创建的Re

我正在编写一些用C语言编写的代码。在此应用程序中,我有一个自定义集合,定义如下:

public class ResultList<T> : IEnumerable<T>
{
  public List<T> Results { get; set; }
  public decimal CenterLatitude { get; set; }
  public decimal CenterLongitude { get; set; }
}

如何执行已创建的ResultList对象的深度复制。我找到了这个帖子:。然而,我不知道怎么做

编码工作量最少的方法是通过
二进制格式化程序进行序列化和反序列化

您可以定义以下扩展方法(取自):

publicstatict-DeepClone(T-obj)
{
使用(var ms=new MemoryStream())
{
var formatter=新的二进制格式化程序();
序列化(ms,obj);
ms.Position=0;
返回(T)格式化程序。反序列化(ms);
}
}
…然后打电话:

ResultList<T> clone = DeepClone(original);
ResultList clone=DeepClone(原始);

ResultList类不能与Jon Skeet的类一起工作的原因之一是它没有实现IClonable接口

在所有需要克隆的类上实现iClonable,例如

public class ResultItem : ICloneable
{
  public object Clone()
  {
    var item = new ResultItem
                 {
                   ID = ID,
                   Name = Name,
                   isLegit = isLegit
                 };
    return item;
  }
}
以及在结果列表上:

public class ResultList<T> : IEnumerable<T>, ICloneable where T : ICloneable
{
  public List<T> Results { get; set; }
  public decimal CenterLatitude { get; set; }
  public decimal CenterLongitude { get; set; }

  public object Clone()
  {
    var list = new ResultList<T>
                 {
                   CenterLatitude = CenterLatitude,
                   CenterLongitude = CenterLongitude,
                   Results = Results.Select(x => x.Clone()).Cast<T>().ToList()
                 };
    return list;
  }
}

这是我需要并编写的东西,它使用反射来复制每个属性(如果指定,还有私有属性)

公共静态类ObjectCloner
{
公共静态T克隆(objectobj,bool deep=false),其中T:new()
{
如果(!(对象为T))
{
抛出新异常(“克隆对象必须与输出类型匹配”);
}
返回(T)克隆(obj,deep);
}
公共静态对象克隆(对象对象对象,布尔深度)
{
if(obj==null)
{
返回null;
}
类型objType=obj.GetType();
if(objType.IsPrimitive | | objType==typeof(string)| | objType.GetConstructors().FirstOrDefault(x=>x.GetParameters().Length==0)==null)
{
返回obj;
}
List properties=objType.GetProperties().ToList();
如果(深)
{
properties.AddRange(objType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic));
}
object newObj=Activator.CreateInstance(objType);
foreach(属性中的var属性)
{
if(prop.GetSetMethod()!=null)
{
object propValue=prop.GetValue(obj,null);
对象克隆=克隆(propValue,deep);
prop.SetValue(newObj,clone,null);
}
}
返回newObj;
}
}

在@Georgi it上展开,我不得不修改他的代码来处理类型继承列表的属性:

public static class ObjectCloner {
    public static T Clone<T>(object obj, bool deep = false) where T : new() {
        if (!(obj is T)) {
            throw new Exception("Cloning object must match output type");
        }

        return (T)Clone(obj, deep);
    }

    public static object Clone(object obj, bool deep) {
        if (obj == null) {
            return null;
        }

        Type objType = obj.GetType();

        if (objType.IsPrimitive || objType == typeof(string) || objType.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 0) == null) {
            return obj;
        }

        List<PropertyInfo> properties = objType.GetProperties().ToList();
        if (deep) {
            properties.AddRange(objType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic));
        }

        object newObj = Activator.CreateInstance(objType);

        foreach (var prop in properties) {
            if (prop.GetSetMethod() != null) {
                var proceed = true;
                if (obj is IList) {
                    var listType = obj.GetType().GetProperty("Item").PropertyType;
                    if (prop.PropertyType == listType) {
                        proceed = false;
                        foreach (var item in obj as IList) {
                            object clone = Clone(item, deep);
                            (newObj as IList).Add(clone);                               
                        }                           
                    }                       
                }

                if (proceed) {
                    object propValue = prop.GetValue(obj, null);
                    object clone = Clone(propValue, deep);
                    prop.SetValue(newObj, clone, null);
                }                   
            }
        }

        return newObj;
    }
}
公共静态类ObjectCloner{
公共静态T克隆(objectobj,bool deep=false),其中T:new(){
如果(!(对象为T)){
抛出新异常(“克隆对象必须与输出类型匹配”);
}
返回(T)克隆(obj,deep);
}
公共静态对象克隆(对象对象对象,布尔深度){
if(obj==null){
返回null;
}
类型objType=obj.GetType();
if(objType.IsPrimitive | | objType==typeof(string)| | objType.GetConstructors().FirstOrDefault(x=>x.GetParameters().Length==0)==null){
返回obj;
}
List properties=objType.GetProperties().ToList();
如果(深){
properties.AddRange(objType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic));
}
object newObj=Activator.CreateInstance(objType);
foreach(属性中的var属性){
if(prop.GetSetMethod()!=null){
var=true;
如果(对象是IList){
var listType=obj.GetType().GetProperty(“项”).PropertyType;
if(prop.PropertyType==listType){
继续=错误;
foreach(对象中的var项作为IList){
对象克隆=克隆(项目,深度);
添加(克隆);
}                           
}                       
}
如果(继续){
object propValue=prop.GetValue(obj,null);
对象克隆=克隆(propValue,deep);
prop.SetValue(newObj,clone,null);
}                   
}
}
返回newObj;
}
}

对于对象的深度覆盖,可以使用以下代码:

public static T DeepCopy<T>(T obj) {
    var str = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
    var ret = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
    return ret;
}
publicstatict-DeepCopy(T-obj){
var str=Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var ret=Newtonsoft.Json.JsonConvert.DeserializeObject(str);
返回ret;
}

您尝试过什么?你收到了什么错误信息?你找到的乔恩·斯基特的代码就我所知很有效。浅拷贝还是深拷贝?为什么你和OP在你的例子中使用了完全相同的数据结构?很好的解释。非常感谢您的帮助。处理继承列表的对象:我将创建第二个答案,因为注释中的代码很糟糕。此代码是错误的:对于字符串,您可以使用“return string.Copy(obj as string)”;“@sborfedor string.Copy已过时。字符串无论如何是不可变的。修改同一引用的唯一方法是使用不安全代码。在这种情况下,您可能不会以任何方式复制粘贴此解决方案。此代码是错误的:对于字符串,您可以使用“return string.copy(obj as string)”;“@sborfedor string.copy已过时。字符串无论如何是不可变的。修改同一引用的唯一方法是使用不安全代码。在这种情况下,您可能不会复制粘贴此解决方案。
resultList.clone();
public static class ObjectCloner
{
    public static T Clone<T>(object obj, bool deep = false) where T : new()
    {
        if (!(obj is T))
        {
            throw new Exception("Cloning object must match output type");
        }

        return (T)Clone(obj, deep);
    }

    public static object Clone(object obj, bool deep)
    {
        if (obj == null)
        {
            return null;
        }

        Type objType = obj.GetType();

        if (objType.IsPrimitive || objType == typeof(string) || objType.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 0) == null)
        {
            return obj;
        }

        List<PropertyInfo> properties = objType.GetProperties().ToList();
        if (deep)
        {
            properties.AddRange(objType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)); 
        }

        object newObj = Activator.CreateInstance(objType);

        foreach (var prop in properties)
        {
            if (prop.GetSetMethod() != null)
            {
                object propValue = prop.GetValue(obj, null);
                object clone = Clone(propValue, deep);
                prop.SetValue(newObj, clone, null);
            }
        }

        return newObj;
    }
}
public static class ObjectCloner {
    public static T Clone<T>(object obj, bool deep = false) where T : new() {
        if (!(obj is T)) {
            throw new Exception("Cloning object must match output type");
        }

        return (T)Clone(obj, deep);
    }

    public static object Clone(object obj, bool deep) {
        if (obj == null) {
            return null;
        }

        Type objType = obj.GetType();

        if (objType.IsPrimitive || objType == typeof(string) || objType.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 0) == null) {
            return obj;
        }

        List<PropertyInfo> properties = objType.GetProperties().ToList();
        if (deep) {
            properties.AddRange(objType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic));
        }

        object newObj = Activator.CreateInstance(objType);

        foreach (var prop in properties) {
            if (prop.GetSetMethod() != null) {
                var proceed = true;
                if (obj is IList) {
                    var listType = obj.GetType().GetProperty("Item").PropertyType;
                    if (prop.PropertyType == listType) {
                        proceed = false;
                        foreach (var item in obj as IList) {
                            object clone = Clone(item, deep);
                            (newObj as IList).Add(clone);                               
                        }                           
                    }                       
                }

                if (proceed) {
                    object propValue = prop.GetValue(obj, null);
                    object clone = Clone(propValue, deep);
                    prop.SetValue(newObj, clone, null);
                }                   
            }
        }

        return newObj;
    }
}
public static T DeepCopy<T>(T obj) {
    var str = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
    var ret = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
    return ret;
}