諮詢區
-
NakedBrunch:
我的項目中有一個對象copy的需求,比如下面這段代碼:
MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();
這段代碼有一點問題,那就是對 newobj 進行的任何修改都會作用到 myobj 上,我不想這樣,我想實現那種深copy,我目前的做法是重新new一個對象,然後逐一將老對象的屬性賦值給新對象,雖然是可以實現,但我覺得應該有更簡單方便的做法?
回答區
-
Michael Cox:
如果你不介意使用第三方工具,可以參考下 ValueInjecter
和 AutoMapper
,它可以完美的實現你的需求,參考如下代碼:
MyObject oldObj; // The existing object to clone
MyObject newObj = new MyObject();
newObj.InjectFrom(oldObj); // Using ValueInjecter syntax
用這些第三方工具,你就不需要像傳統那樣copy了,也避免了 model 需實現 ISerializable 或 ICloneable 接口的尷尬,其實這是 MVC/MVVM
開發模式下的 DTO 通用做法。
-
johnc:
你可以使用 JSON.NET 去實現,它可以非常輕量級的實現,不需要讓你的類打上[Serializable]
標記,參考如下代碼:
public static T CloneJson<T>(this T source)
{
// Don't serialize a null object, simply return the default for that object
if (ReferenceEquals(source, null)) return default;
var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}
-
Michael White:
我也碰到了這種問題,我覺得序列化是一條路,這裏我把它序列化爲xml,參考如下:
static public class SerializeHelper
{
public static T DeserializeXML<T>(string xmlData) where T:new()
{
if (string.IsNullOrEmpty(xmlData))
return default(T);
TextReader tr = new StringReader(xmlData);
T DocItms = new T();
XmlSerializer xms = new XmlSerializer(DocItms.GetType());
DocItms = (T)xms.Deserialize(tr);
return DocItms == null ? default(T) : DocItms;
}
public static string SeralizeObjectToXML<T>(T xmlObject)
{
StringBuilder sbTR = new StringBuilder();
XmlSerializer xmsTR = new XmlSerializer(xmlObject.GetType());
XmlWriterSettings xwsTR = new XmlWriterSettings();
XmlWriter xmwTR = XmlWriter.Create(sbTR, xwsTR);
xmsTR.Serialize(xmwTR,xmlObject);
return sbTR.ToString();
}
public static T CloneObject<T>(T objClone) where T:new()
{
string GetString = SerializeHelper.SeralizeObjectToXML<T>(objClone);
return SerializeHelper.DeserializeXML<T>(GetString);
}
}
點評區
相信深copy在各位項目開發中是必然會遇到的問題,我在很長一段時間內都是使用 JSON.NET
去實現,就像 johnc
大佬提供的代碼一樣,簡單粗暴,同時三位大佬都提供了相應方法,這裏學習了!
本文分享自微信公衆號 - 一線碼農聊技術(dotnetfly)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。