当前位置:网站首页>[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
边栏推荐
- How much do you know about the process of the interview
- Copy constructor shallow copy and deep copy
- Grpc gateway based on Ocelot
- Use of shell sed command
- ASP. Net core reads the configuration file in the class library project
- . net type transfer
- Bytevcharts visual chart library, I have everything you want
- Handwritten event publish subscribe framework
- Shell-awk命令的使用
- Redis docker installation
猜你喜欢
Path environment variable
[pimf] openharmony paper Club - what is the experience of wandering in ACM survey
自定义my_strcpy与库strcpy【模拟实现字符串相关函数】
快时钟同步慢时钟域下的异步控制信号slow clk to fast clk
Milvus 2.0 質量保障系統詳解
文件操作《二》(5000字总结篇)
org. apache. parquet. schema. InvalidSchemaException: A group type can not be empty. Parquet does not su
网络安全之渗透靶场实战详解
Nacos + aspnetcore + Ocelot actual combat code
groutine
随机推荐
Baidu Map Case - Zoom component, map scale component
PHP efficiently reads large files and processes data
New keyword learning and summary
Nodejs installation and environment configuration
Website_ Collection
Detailed explanation of information abstract, digital signature, digital certificate, symmetric encryption and asymmetric encryption
Regular filtering of Intranet addresses and segments
STM32__ 03 - beginner timer
Decimal format decimal / datetime conversion processing
Detailed explanation of C webpai route
Milvus 2.0 质量保障系统详解
VLAN advanced technology, VLAN aggregation, super VLAN, sub VLAN
Use between nodejs modules
BUG_ me
freeCodeCamp----shape_ Calculator exercise
Change the password after installing MySQL in Linux
Smart doc + Torna generate interface document
El date picker limits the selection range from the current time to two months ago
1-3 nodejs installation list configuration and project environment
Rtklib 2.4.3 source code Notes