Skip to content

Commit f10a307

Browse files
committed
feat(Network): 为MessageObject添加深克隆和浅克隆方法
添加DeepClone和ShallowClone方法以支持消息对象的克隆功能 深克隆优先使用ProtoBuf,其次使用JSON序列化方式 浅克隆使用MemberwiseClone实现引用复制
1 parent 492eac3 commit f10a307

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

Runtime/Network/Base/MessageObject.cs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using GameFrameX.Runtime;
1+
using System;
2+
using System.IO;
3+
using GameFrameX.Runtime;
24
using Newtonsoft.Json;
35
#if ENABLE_GAME_FRAME_X_PROTOBUF
46
using ProtoBuf;
@@ -52,5 +54,61 @@ public override string ToString()
5254
public virtual void Clear()
5355
{
5456
}
57+
58+
/// <summary>
59+
/// 深克隆。
60+
/// 优先使用 ProtoBuf(如果启用),否则使用高效的反射缓存方式。
61+
/// 也可以通过参数强制使用 JSON 方式。
62+
/// </summary>
63+
/// <typeparam name="T">消息类型</typeparam>
64+
/// <param name="useJson">是否强制使用 JSON 进行克隆(较慢但兼容性最好)</param>
65+
/// <returns>克隆后的对象</returns>
66+
public T DeepClone<T>(bool useJson = false) where T : MessageObject, new()
67+
{
68+
T clone;
69+
70+
if (useJson)
71+
{
72+
var json = JsonConvert.SerializeObject(this);
73+
clone = JsonConvert.DeserializeObject<T>(json);
74+
}
75+
else
76+
{
77+
#if ENABLE_GAME_FRAME_X_PROTOBUF
78+
// 使用 ProtoBuf 进行深克隆,这是最高效的方式
79+
try
80+
{
81+
using (var stream = new MemoryStream())
82+
{
83+
Serializer.Serialize(stream, this);
84+
stream.Seek(0, SeekOrigin.Begin);
85+
clone = Serializer.Deserialize<T>(stream);
86+
}
87+
}
88+
catch (Exception)
89+
{
90+
throw new Exception($"ProtoBuf 深克隆失败,类型:{typeof(T).FullName}");
91+
}
92+
#endif
93+
}
94+
95+
// 确保每个克隆体都有唯一的 ID
96+
if (clone != null)
97+
{
98+
clone.UpdateUniqueId();
99+
}
100+
101+
return clone;
102+
}
103+
104+
/// <summary>
105+
/// 浅克隆。
106+
/// 仅复制对象的引用,不递归复制子对象。
107+
/// </summary>
108+
/// <returns>浅克隆后的对象</returns>
109+
public MessageObject ShallowClone()
110+
{
111+
return (MessageObject)MemberwiseClone();
112+
}
55113
}
56114
}

0 commit comments

Comments
 (0)