当前位置:网站首页>[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
边栏推荐
猜你喜欢

Further study of data visualization

Node access to Alipay open platform sandbox to achieve payment function
![[PROJECT] small hat takeout (8)](/img/54/0187eeb637f4dcd4ad3969b00e2b77.png)
[PROJECT] small hat takeout (8)
![Customize my_ Strcpy and library strcpy [analog implementation of string related functions]](/img/71/a6a0c7b0e652d2b807f259f7cbf139.png)
Customize my_ Strcpy and library strcpy [analog implementation of string related functions]

Nodejs reads the local JSON file through require. Unexpected token / in JSON at position appears

Derivation of Σ GL perspective projection matrix

ClickHouse-表引擎

Detailed explanation of Milvus 2.0 quality assurance system
![[registration] tf54: engineer growth map and excellent R & D organization building](/img/12/7aece45fbc9643c97cdda94b405118.jpg)
[registration] tf54: engineer growth map and excellent R & D organization building

VLAN advanced technology, VLAN aggregation, super VLAN, sub VLAN
随机推荐
[PROJECT] small hat takeout (8)
Expression "func" tSource, object "to expression" func "tSource, object" []
Generate random numbers with high quality and Gaussian distribution
Blue Bridge Cup provincial road 06 -- the second game of the 12th provincial competition
织梦DEDECMS安全设置指南
. net type transfer
Decimal format decimal / datetime conversion processing
ASP. Net core reads the configuration file in the class library project
【解决报错】Error in v-on handler: “TypeError: Cannot read property ‘resetFields’ of undefined”
Grpc gateway based on Ocelot
【生活中的逻辑谬误】稻草人谬误和无力反驳不算证明
Use of shell sed command
Promise (IV)
Detailed explanation of Milvus 2.0 quality assurance system
freeCodeCamp----prob_ Calculator exercise
Document operation II (5000 word summary)
Zhimeng dedecms security setup Guide
Baidu Map Case - modify map style
TypeError: set_ figure_ params() got an unexpected keyword argument ‘figsize‘
Paging the list collection