当前位置:网站首页>[C] thoroughly understand the deep copy
[C] thoroughly understand the deep copy
2022-04-23 17:08:00 【code bean】
Every language has the concept of deep copy , In fact, they are all the same , This time from C# Interpretation from the perspective of .
C# There are value types and reference types . Value type , Such as int There are no shallow and deep problems , Direct assignment is over .
Reference type , For example, our custom class . adopt new The way to create ,new What is returned is actually “ The pointer ”,
Or quote , He himself is on the stack , however new The allocated space is on the heap . If you assign a value to a reference directly ,
It's quite a change “ The pointer ” The direction of . Heap memory previously managed by him , It was suspended , Finally, no one pointed to it , Will be recycled by the garbage collection mechanism .
such as , I customize a class .
public class Box
{
public double height; // Height
public double width; // Width
}
then new Two objects , And will b1 Directly assign to b2
Box b1 = new Box();
Box b2 = new Box();
b2 = b1;
b2.width = 5; // change b2 influence b1
Console.WriteLine(b1.width);
here b2 and b1 Pointing to the same block of memory ,b2 The previously allocated memory is suspended , Finally being GC Recycling .
Then if you don't want to , I want to copy a separate b2(b2 The change of does not affect b1), Then the only way is to copy one by one .
public static Box FixDeepCopy(double height, double width)
{
Box b = new Box();
b.height = height;
b.width = width;
return b;
}
Here we notice , We haven't changed b The direction of , therefore b It points to yourself at the beginning new Out of memory . Due to the assignment one by one , So at this time, the deep copy is successful .
But it's too much trouble , Different types , To write different deep copy functions , And as classes become more complex , The more complicated the method is .
So the following three methods , Help you with , Observe carefully , In fact, these three methods , In fact, it also copies the member variables one by one ,
It's just a generalization .
Not much said , Go straight to the code :
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace DeepCopyTest
{
internal class Program
{
[Serializable]
public class Box
{
public double height; // Height
public double width; // Width
}
public static Box FixDeepCopy(double height, double width)
{
Box b = new Box();
b.height = height;
b.width = width;
return b;
}
public static T DeepCopyByBin<T>(T obj)
{
object retval;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
// Sequence into a stream
bf.Serialize(ms, obj);
// Sets the position in the current stream to the specified value . That is from SeekOrigin.Begin The offset 0 A place .
ms.Seek(0, SeekOrigin.Begin);
// Anti serialization into objects
retval = bf.Deserialize(ms);
ms.Close();
}
return (T)retval;
}
/// <summary>
/// Note that you need to add... To the class [Serializable]
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T DeepCopyByReflect<T>(T obj)
{
// If it is a string or value type, it directly returns
if (obj is string || obj.GetType().IsValueType) return obj;
object retval = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
foreach (FieldInfo field in fields)
{
try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }
catch { }
}
return (T)retval;
}
static void Main(string[] args)
{
Box b1 = new Box();
Box b2 = new Box();
Box b3 = new Box();
Box b4 = new Box();
Console.WriteLine(b1.width);
// The way of direct assignment
b2 = b1;
b2.width = 5; // change b2 influence b1
Console.WriteLine(b1.width);
Console.WriteLine("-------------- The way 1----------------------");
// Deep copy
b2 = DeepCopyByBin(b1);
b2.width = 6; // change b2 No effect b1
Console.WriteLine(b1.width);
Console.WriteLine("--------------- The way 2---------------------");
// Deep copy
b3 = DeepCopyByReflect(b1);
b3.width = 7; // change b5 No effect b1
Console.WriteLine(b1.width);
Console.WriteLine("---------------- The way 3--------------------");
// Deep copy ( You need to install the package :Newtonsoft.Json)
b4 = JsonConvert.DeserializeObject<Box>(JsonConvert.SerializeObject(b1)); // A deep clone
b4.width = 789; // change b4 No effect b1
Console.WriteLine(b1.width);
Console.ReadKey();
}
}
}
Summary :
1 Sensory JsonConvert Most convenient , You need to install a package yourself Newtonsoft.Json( This bag is too common )
JsonConvert.DeserializeObject<Box>(JsonConvert.SerializeObject(b1));
2 Use BinaryFormatter The way , Note that you need to add a serializable feature to the class [Serializable], Otherwise, the operation will report an error .
It's more direct , Copy the whole memory directly .
3 Finally, reflect this way , Pay attention to , Because you can see it , It uses recursion , To retrieve every object .
If the object is too complex , There may be a problem .
版权声明
本文为[code bean]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231702084859.html
边栏推荐
- Installing labellmg tutorial in Windows
- Use of shell sed command
- Lock锁
- freeCodeCamp----prob_ Calculator exercise
- 【解决报错】Error in v-on handler: “TypeError: Cannot read property ‘resetFields’ of undefined”
- websocket
- _ Mold_ Board_
- Input file upload
- Nodejs reads the local JSON file through require. Unexpected token / in JSON at position appears
- PHP高效读大文件处理数据
猜你喜欢
Detailed explanation of Milvus 2.0 quality assurance system
Milvus 2.0 质量保障系统详解
Lock锁
Scope and scope chain in JS
Lock lock
Devexpress GridView add select all columns
Path environment variable
TypeError: set_ figure_ params() got an unexpected keyword argument ‘figsize‘
Document operation II (5000 word summary)
. net type transfer
随机推荐
文件操作《二》(5000字总结篇)
◰ GL shader handler encapsulation
拷贝构造函数 浅拷贝与深拷贝
Preliminary understanding of promse
Copy constructor shallow copy and deep copy
Calculate pie chart percentage
C# Task. Delay and thread The difference between sleep
ClickHouse-SQL 操作
Kingdee Cloud Star API calling practice
◰ GL shadow map core steps
Tencent resolves the address according to the IP address
Promise (I)
Detailed explanation of Milvus 2.0 quality assurance system
Shell-cut命令的使用
1-4 configuration executable script of nodejs installation
Shortcut keys (multiline)
VLAN高级技术,VLAN聚合,超级Super VLAN ,Sub VLAN
Use of shell awk command
Grpc gateway based on Ocelot
TypeError: set_figure_params() got an unexpected keyword argument ‘figsize‘