Dictionary<TKey, TValue>를 deep copy하는 방법
예전에 XmlSerializer를 이용한 값 복사를 설명했었습니다.
XML Serializer 를 이용한 값 복사
; https://www.sysnet.pe.kr/2/0/577
아쉽게도
Dictionary 제네릭 타입의 경우 XmlSerializer를 사용하면,
XmlSerializer xs = new XmlSerializer(typeof(Dictionary<string, int>));
생성자에서 다음과 같은 예외가 발생합니다.
System.NotSupportedException occurred
HResult=0x80131515
Message=The type System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] is not supported because it implements IDictionary.
Source=System.Xml
StackTrace:
at System.Xml.Serialization.TypeScope.GetDefaultIndexer(Type type, String memberInfo)
at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference)
at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
at System.Xml.Serialization.ModelScope.GetTypeModel(Type type, Boolean directReference)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type)
at ConsoleApp1.Program.Main(String[] args) in C:\ConsoleApp1\ConsoleApp1\Program.cs:line 36
IDictionary를 구현한 타입은 지원하지 않기 때문입니다. (참고로,
DataContractSerializer를 사용하면 직렬화가 됩니다.) 다행인 점은, Dictionary 타입도 ISerializable을 구현하고 있기 때문에 BinaryFormatter는 사용할 수 있습니다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, int> dict = new Dictionary<string, int>();
dict.Add("5", 5);
dict.Add("6", 6);
Dictionary<string, int> dict2 = CloneData(dict);
dict.Remove("6");
foreach (var item in dict)
{
Console.WriteLine(item.Value);
}
Console.WriteLine();
foreach (var item in dict2)
{
Console.WriteLine(item.Value);
}
}
public static TData CloneData<TData>(TData data) where TData : class
{
if (data == null)
{
return null;
}
MemoryStream ms = new MemoryStream();
BinaryFormatter xs = new BinaryFormatter();
xs.Serialize(ms, data);
ms.Position = 0;
return (TData)xs.Deserialize(ms);
}
}
}
/*
// 출력 결과
5
5
6
*/
당연한 이야기지만, 위의 코드는 범용적으로 편리함 차원에서 유용할 뿐 성능이 필요한 곳에서는 개별 복사를 하는 것이 좋습니다.
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]