大卫的答案很简单,如果您不介意分配一个额外的数组来保存正在复制的字符串的临时副本。如果你想减少内存使用,特别是如果列表很大,循环会更好:
var
MyList: TList<String>;
I: Integer;
begin
MyList := TList<String>.Create;
try
MyList.Capacity := MyListBox.Items.Count;
for i := 0 to MyList.Capacity-1 do
MyList.Add(MyListBox.Items[I]);
...
finally
MyList.Free;
end;
end;
或者:
var
MyList: TList<String>;
S: String;
begin
MyList := TList<String>.Create;
try
MyList.Capacity := MyListBox.Items.Count;
for S in MyListBox.Items do
MyList.Add(S);
...
finally
MyList.Free;
end;
end;
但是,如果您不想手动循环,那么我建议您创建一个自定义枚举器,以便您可以将TStrings
数据直接传递给TList<String>
并让它为您复制字符串:
type
TStringsEnumeratorWrapper = class(TEnumerator<String>)
protected
FEnum: TStringsEnumerator;
function DoGetCurrent: String; override;
function DoMoveNext: Boolean; override;
public
constructor Create(AStrings: TStrings);
destructor Destroy; override;
end;
constructor TStringsEnumeratorWrapper.Create(AStrings: TStrings);
begin
inherited Create;
FEnum := AStrings.GetEnumerator;
end;
destructor TStringsEnumeratorWrapper.Destroy;
begin
FEnum.Free;
inherited Destroy;
end;
function TStringsEnumeratorWrapper.DoGetCurrent: String;
begin
Result := FEnum.Current;
end;
function TStringsEnumeratorWrapper.DoMoveNext: Boolean;
begin
Result := FEnum.MoveNext;
end;
type
TStringsEnumerableWrapper = class(TEnumerable<String>)
protected
FStrings: TStrings;
function DoGetEnumerator: TEnumerator<T>; override;
public
constructor Create(AStrings: TStrings);
end;
constructor TStringsEnumerableWrapper.Create(AStrings: TStrings);
begin
inherited Create;
FStrings := AStrings;
end;
function TStringsEnumerableWrapper.DoGetEnumerator: TEnumerator<T>;
begin
Result := TStringsEnumeratorWrapper.Create(FStrings);
end;
var
MyList: TList<String>;
Enum: TStringsEnumerableWrapper;
begin
MyList := TList<String>.Create;
try
MyList.Capacity := MyListBox.Items.Count;
Enum := TStringsEnumerableWrapper.Create(MyListBox.Items);
try
MyList.AddRange(Enum);
finally
Enum.Free;
end;
...
finally
MyList.Free;
end;
end;
或者:
type
TStringsEnumeratorWrapper = class(TObject, IEnumerator<String>)
protected
FEnum: TStringsEnumerator;
public
constructor Create(AStrings: TStrings);
destructor Destroy; override;
function GetCurrent: String;
function MoveNext: Boolean;
procedure Reset;
end;
constructor TStringsEnumeratorWrapper.Create(AStrings: TStrings);
begin
inherited Create;
FEnum := AStrings.GetEnumerator;
end;
destructor TStringsEnumeratorWrapper.Destroy;
begin
FEnum.Free;
inherited Destroy;
end;
function TStringsEnumeratorWrapper.GetCurrent: String;
begin
Result := FEnum.Current;
end;
function TStringsEnumeratorWrapper.MoveNext: Boolean;
begin
Result := FEnum.MoveNext;
end;
procedure TStringsEnumeratorWrapper.Reset;
begin
//FEnum.Reset;
end;
type
TStringsEnumerableWrapper = class(TObject, IEnumerable<String>)
protected
FStrings: TStrings;
public
constructor Create(AStrings: TStrings);
function GetEnumerator: IEnumerator<String>;
end;
constructor TStringsEnumerableWrapper.Create(AStrings: TStrings);
begin
inherited Create;
FStrings := AStrings;
end;
function TStringsEnumerableWrapper.GetEnumerator: IEnumerator<String>;
begin
Result := TStringsEnumeratorWrapper.Create(FStrings);
end;
var
MyList: TList<String>;
begin
MyList := TList<String>.Create;
try
MyList.Capacity := MyListBox.Items.Count;
MyList.AddRange(TStringsEnumerableWrapper.Create(MyListBox.Items));
...
finally
MyList.Free;
end;
end;
诚然,不像大卫的回答那样优雅,但枚举器旨在帮助更轻松地循环遍历列表项(因此允许创建for..in
循环语法)。