有没有简单的方法将TDictionary内容复制到另一个?

时间:2012-03-20 13:02:47

标签: delphi generics delphi-xe2 deep-copy tdictionary

有一种方法或简单的方法如何将一个TDictionary内容复制到另一个中? 假设我有以下声明

type
  TItemKey = record
    ItemID: Integer;
    ItemType: Integer;
  end;
  TItemData = record
    Name: string;
    Surname: string;
  end;
  TItems = TDictionary<TItemKey, TItemData>;

var
  // the Source and Target have the same types
  Source, Target: TItems;
begin
  // I can't find the way how to copy source to target
end;

我想将源1:1复制到目标。有这样的方法吗?

谢谢!

4 个答案:

答案 0 :(得分:22)

TDictionary有一个构造函数,允许您传入另一个集合对象,该对象将通过复制原始内容来创建新对象。那是你在找什么?

constructor Create(Collection: TEnumerable<TPair<TKey,TValue>>); overload;

所以你会用

Target := TItems.Create(Source);

目标将被创建为Source的副本(或至少包含Source中的所有项目)。

答案 1 :(得分:1)

如果你想更进一步,这是另一种方法:

type
  TDictionaryHelpers<TKey, TValue> = class
  public
    class procedure CopyDictionary(ASource, ATarget: TDictionary<TKey,TValue>);
  end;

...implementation...

{ TDictionaryHelpers<TKey, TValue> }

class procedure TDictionaryHelpers<TKey, TValue>.CopyDictionary(ASource,
  ATarget: TDictionary<TKey, TValue>);
var
  LKey: TKey;
begin
  for LKey in ASource.Keys do
    ATarget.Add(LKey, ASource.Items[ LKey ] );
end;

根据您对的定义使用

TDictionaryHelpers<TItemKey, TItemData>.CopyDictionary(LSource, LTarget);

答案 2 :(得分:0)

我认为这应该可以解决问题:

var
  LSource, LTarget: TItems;
  LKey: TItemKey;
begin
  LSource := TItems.Create;
  LTarget := TItems.Create;
  try
    for LKey in LSource.Keys do 
      LTarget.Add(LKey, LSource.Items[ LKey ]);
  finally
    LSource.Free;
    LTarget.Free;
  end; // tryf
end;

答案 3 :(得分:0)

在需要赋值时构造一个新实例可能会产生副作用,例如其他地方的对象引用失效。泛型方法可能不会深度复制引用类型。

我会采用更简单的方法:

unit uExample;

interface

uses
  System.Generics.Collections;

type 
  TStringStringDictionary = class(TDictionary<string,string>)
  public
    procedure Assign(const aSSD: TStringStringDictionary);
  end;

implementation

procedure TStringStringDictionary.Assign(const aSSD: TStringStringDictionary );
var
  lKey: string;
begin
  Clear;
  for lKey in aSSD.Keys do
    Add(lKey, aSSD.Items[lKey]); // Or use copy constructors for objects to be duplicated
end;

end.