c#中的对象深拷贝和浅拷贝-kb88凯时官网登录

来自:
时间:2024-05-10
阅读:

概述

在c#中,对象拷贝是指将一个对象的副本创建到另一个对象中。对象拷贝通常用于数据传输或创建对象的新实例。

c#中有两种主要的拷贝方式:浅拷贝和深拷贝

1. 浅拷贝

浅拷贝是指只拷贝对象的值类型成员,而引用类型成员的引用则保持不变。这意味着新的对象和原始对象将共享所有引用类型成员的实际对象。

实现方式

  • this.memberwiseclone();

示例代码

实体

public class person
{
    public person()
    {
        this.address = new address();
    }
    public string name { get; set; }
     public int age { get; set; }
    public address address { get; set; }
    public person clone()
    {
        return (person)this.memberwiseclone();
    }
}
public class address
{
    public string street { get; set; }
    public string city { get; set; }
}

调用

 person person1 = new person()
 {
     name = "张三",
     address = new address()
     {
         city = "北京",
     }
 };
 person person2 = person1.clone();//浅拷贝
 //修改原对象的属性
 person1.address.city = "上海";
 //修改副本对象的属性
 person2.name = "李四";
 person2.address.city = "昆明";
 string result = $"原对象{jsonconvert.serializeobject(person1)}。副本{jsonconvert.serializeobject(person2)}";
 messagebox.show($"浅拷贝:原对象和副本修改引用类型属性后相互影响。{result}");

2. 深拷贝

深拷贝是指不仅拷贝对象的值类型成员,而且还拷贝所有引用类型成员的实际对象。这意味着新的对象将拥有其引用类型成员的完全独立副本。

实现方式

  • 反射
  • 序列化
  • 对象映射(三方开源如tinymapper、automapper)。

示例代码

/// 
/// 深拷贝
/// 
public static void copy2()
{
    person person1 = new person()
    {
        name = "张三",
        address = new address()
        {
            city = "北京",
        }
    };
    //person person2 = createdeepcopy(person1);//深拷贝1反射
    // person person2 =jsonconvert.deserializeobject(jsonconvert.serializeobject(person1));//深拷贝2序列化
    person person2 =person1.mapto();//深拷贝3对象映射
    //修改原对象的属性
    person1.address.city = "上海";
    //修改副本对象的属性
    person2.name = "李四";
    person2.address.city = "昆明";
    string result = $"原对象{jsonconvert.serializeobject(person1)}。副本{jsonconvert.serializeobject(person2)}";
    messagebox.show($"深拷贝:原对象和副本不相互影响。{result}");
}
/// 
/// 使用反射进行深拷贝
/// 
/// 
/// 
static t createdeepcopy(t original)
{
    if (original == null)
    {
        return default(t);
    }
    type type = original.gettype();
    object newobject = activator.createinstance(type);
    foreach (fieldinfo fieldinfo in type.getfields())
    {
        if (fieldinfo.isstatic)
        {
            continue;
        }
        object value = fieldinfo.getvalue(original);
        fieldinfo.setvalue(newobject, createdeepcopy(value));
    }
    return (t)newobject;
}

总结

浅拷贝通常用于数据传输,因为它是快速且有效的。但是,如果需要避免意外修改原始对象,则应使用深拷贝。

以下是一些有关何时使用浅拷贝和深拷贝的准则:

  • 使用浅拷贝:
    • 当需要快速创建对象副本时
    • 当原始对象不可变时
    • 当原始对象和副本不会同时使用时
  • 使用深拷贝:
    • 当需要避免意外修改原始对象时
    • 当原始对象和副本需要同时使用时
    • 当原始对象包含引用类型成员时

引用

返回顶部
顶部
网站地图