2013-04-11 2 views
-3

У меня есть следующий метод, который делает deep copy из словаря:Как сделать глубокую копию шаблона словарь

public static Dictionary<string, MyClass> deepCopyDic(Dictionary<string, MyClass> src) 
{ 
    //Copies a dictionary with all of its elements 
    //RETURN: 
    //  = Dictionary copy 
    Dictionary<string, MyClass> dic = new Dictionary<string, MyClass>(); 
    for (int i = 0; i < src.Count; i++) 
    { 
     dic.Add(src.ElementAt(i).Key, new MyClass(src.ElementAt(i).Value)); 
    } 

    return dic; 
} 

мне было интересно, могу ли я каким-то образом сделать его в шаблон? Мне нужен MyClass, чтобы быть шаблоном.

+0

... шаблон для чего? –

+0

@JeremyHolovacs: для 'MyClass' будет' MyOtherClass' или 'MyAnotherClass' и т. Д. – ahmd0

+0

вы имеете в виду абстрактный класс? Интерфейс? –

ответ

6

Вы можете использовать Generics с where TValue : ICloneable ограничения:

public static Dictionary<TKey, TValue> deepCopyDic<TKey, TValue>(Dictionary<TKey, TValue> src) 
    where TValue : ICloneable 
{ 
    //Copies a dictionary with all of its elements 
    //RETURN: 
    //  = Dictionary copy 
    Dictionary<TKey, TValue> dic = new Dictionary<TKey, TValue>(); 
    foreach (var item in src) 
    { 
     dic.Add(item.Key, (TValue)item.Value.Clone()); 
    } 

    return dic; 
} 

Вы должны реализовать интерфейс ICloneable в каждом классе вы хотели бы передать в этот метод.

Или немного улучшенная версия, с Key клонируют, а также:

public static Dictionary<TKey, TValue> deepCopyDic<TKey, TValue>(Dictionary<TKey, TValue> src) 
    where TValue : ICloneable 
    where TKey : ICloneable 
{ 
    return src.ToDictionary(i => (TKey)i.Key.Clone(), i => (TValue)i.Value.Clone()); 
} 
+0

Спасибо. Это то, чего мне не хватало :) – ahmd0

+0

Так что вместо 'ICloneable' можно просто скопировать его с помощью' new' и конструктора? – ahmd0

+0

Нет, вы не можете, потому что вы не можете установить общие ограничения типа 'where TValue: new (TValue)' – MarcinJuraszek

1

Сериализованный подход является единственным способом, как указано выше. ICloneable не гарантирует, что все свойства в клонированном объекте не присваивают ссылки, если вы не имеете полного контроля над объектом, который никогда не является хорошим предположением, особенно в большой команде.

Единственная полоса сериализованного подхода заключается в том, что все объекты, передаваемые в словаре, сериализуемы. Кроме того, сериализация не всегда очень эффективна из-за чрезмерного использования Reflection, которое происходит, которое не должно использоваться в областях с высокой степенью предварительной обработки кода.

Я решил эту проблему, используя подход, известный как быстрая сериализация, но для этого требуется, чтобы все объекты, которые вы планируете клонировать, поддерживали определенный интерфейс. Это всегда скорость и сложность.

+0

О, я забыл упомянуть. Словари не являются Serializable. Итак, если вы планируете использовать технику Serializable, вам нужно будет перебирать все ваши объекты в словаре. – code5

1

Вы можете использовать опцию конструктор копирования:

Dictionary<string, int> copy = new Dictionary<string, int>(dictionary); 

Таким образом, вы сделать глубокую копию словаря. Link оригинальное сообщение.

Смежные вопросы