질문 : 딥 클로닝 개체
다음과 같이하고 싶습니다.
MyObject myObj = GetMyObj(); // Create and fill a new object
MyObject newObj = myObj.Clone();
그런 다음 원래 개체에 반영되지 않은 새 개체를 변경합니다.
저는이 기능이 자주 필요하지 않으므로 필요할 때 새 객체를 만든 다음 각 속성을 개별적으로 복사하는 방법을 사용했지만 항상 더 좋고 우아한 처리 방법이 있다는 느낌을받습니다. 그 상황.
원본 개체에 변경 사항이 반영되지 않고 복제 된 개체를 수정할 수 있도록 개체를 복제하거나 전체 복사하려면 어떻게해야합니까?
답변
한 가지 접근 방식은 ICloneable
인터페이스 를 구현하는 것이지만 (여기 에 설명되어 있으므로 역류하지 않겠습니다) 여기에 얼마 전에 The Code Project에서 찾은 멋진 딥 클론 객체 복사기가 있습니다. 다른 곳에서 언급했듯이 객체를 직렬화 할 수 있어야합니다.
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
/// <summary>
/// Perform a deep copy of the object via serialization.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>A deep copy of the object.</returns>
public static T Clone<T>(T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", nameof(source));
}
// Don't serialize a null object, simply return the default for that object
if (ReferenceEquals(source, null)) return default;
using var Stream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
아이디어는 개체를 직렬화 한 다음 새로운 개체로 역 직렬화하는 것입니다. 이점은 객체가 너무 복잡해지면 모든 것을 복제하는 것에 대해 걱정할 필요가 없다는 것입니다.
C # 3.0의 새로운 확장 메서드 를 사용하려는 경우 다음 서명을 갖도록 메서드를 변경합니다.
public static T Clone<T>(this T source)
{
// ...
}
이제 메서드 호출은 단순히 objectBeingCloned.Clone();
.
편집 (2015 년 1 월 10 일) 최근에 (Newtonsoft) Json을 사용하여이 작업을 시작했음을 언급하기 위해 이것을 다시 방문 할 것이라고 생각했습니다 . 더 가벼워 야하며 [Serializable] 태그의 오버 헤드를 피해야합니다. ( NB @atconway는 개인 구성원이 JSON 방법을 사용하여 복제되지 않는다는 의견을 지적했습니다)
/// <summary>
/// Perform a deep Copy of the object, using Json as a serialization method. NOTE: Private members are not cloned using this method.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
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;
// initialize inner objects individually
// for example in default constructor some list property initialized with some values,
// but in 'source' these items are cleaned -
// without ObjectCreationHandling.Replace default constructor values will be added to result
var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace};
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}
출처 : https://stackoverflow.com/questions/78536/deep-cloning-objects
'개발관련 > other' 카테고리의 다른 글
npm 패키지에서 "at"(@) 접두어의 의미 (0) | 2021.11.22 |
---|---|
LINQ에서 GroupBy 여러 열을 수행하는 방법 (0) | 2021.11.19 |
하위 디렉토리 및 시간이있는 디렉토리에서 최근 수정 된 파일을 재귀 적으로 찾고 나열하는 방법 (0) | 2021.11.18 |
SQL Management Studio에서 다른 포트 번호를 지정하는 방법 (0) | 2021.11.18 |
Xcode 7 오류 :“Missing iOS Distribution signing identity for ...” (0) | 2021.11.17 |