首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#对象的深层副本

C#对象的深层副本
EN

Stack Overflow用户
提问于 2012-06-18 04:01:52
回答 5查看 31.4K关注 0票数 8

我正在编写一些用C#编写的代码。在这个应用中,我有一个自定义的集合,定义如下:

代码语言:javascript
运行
复制
public class ResultList<T> : IEnumerable<T>
{
  public List<T> Results { get; set; }
  public decimal CenterLatitude { get; set; }
  public decimal CenterLongitude { get; set; }
}

Results使用的类型是三种自定义类型之一。每个自定义类型的属性都是原始类型(int、string、bools、int?、bool?)。以下是其中一种自定义类型的示例:

代码语言:javascript
运行
复制
public class ResultItem
{
  public int ID { get; set; }
  public string Name { get; set; }
  public bool? isLegit { get; set; }
}

如何执行我创建的ResultList对象的深层副本。我找到了这篇文章:Generic method to create deep copy of all elements in a collection。然而,我想不出该怎么做。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-06-18 04:51:12

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

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

代码语言:javascript
运行
复制
public class ResultItem : ICloneable
{
  public object Clone()
  {
    var item = new ResultItem
                 {
                   ID = ID,
                   Name = Name,
                   isLegit = isLegit
                 };
    return item;
  }
}

也是在ResultList上:

代码语言:javascript
运行
复制
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;
  }
}

然后创建对象的深层副本:

代码语言:javascript
运行
复制
resultList.clone();
票数 9
EN

Stack Overflow用户

发布于 2012-06-18 04:07:32

涉及最少编码工作的方法是通过BinaryFormatter序列化和反序列化的方法。

您可以定义以下扩展方法(取自Kilhoffer’s answer):

代码语言:javascript
运行
复制
public static T DeepClone<T>(T obj)
{
    using (var ms = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(ms, obj);
        ms.Position = 0;
        return (T)formatter.Deserialize(ms);
    }
}

…然后给我打电话:

代码语言:javascript
运行
复制
ResultList<T> clone = DeepClone(original);
票数 16
EN

Stack Overflow用户

发布于 2015-01-14 23:54:02

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

代码语言:javascript
运行
复制
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;
    }
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11074381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档