Delphi 2009부터 추가된 Generic이 있다.
간단하게 말하자면 C++의 Template라고 생각하면 되겠다.
이제 자바나 C++ 포팅할때도 충분히 쉽게 포팅할수 있게 되었다.
Generics.Collections를 보면 List 등의 클래스를 쉽게 포팅할수 있는 좋은 클래스가 많이 있다.
자바쪽 소스를 포팅하다보니 클래스에 ToArray라는 함수가 있는데 열어봐도 없길래 Generics.Collections 유닛을 열어보니 주석처리가 되어있다.
이유는 pending compiler support 라고 씌여있다.
흠... 없다면 상속해서 만들어주면 되겠군.
TObject를 담을 때 유용한 TObjectList를 상속받아서 하나 만들어보자.
type
TMyObjectList<T: class> = class( TObjectList<T> )
public
function ToArray: TArray<T>;
class procedure FreeArray( AMyArray: TArray<T> );
end;
implementation
class procedure TMyObjectList<T>.FreeArray(AMyArray: TArray<T>);
var
I: Integer;
begin
for I := 0 to Length(AMyArray) - 1 do
FreeAndNil( AMyArray[I] );
SetLength( AMyArray, 0 );
end;
function TMyObjectList<T>.ToArray: TArray<T>;
var
i: Integer;
begin
SetLength(Result, Count);
for i := 0 to Count - 1 do
Result[i] := Items[i];
end;
TMyObjectList<T: class> = class( TObjectList<T> )
public
function ToArray: TArray<T>;
class procedure FreeArray( AMyArray: TArray<T> );
end;
implementation
class procedure TMyObjectList<T>.FreeArray(AMyArray: TArray<T>);
var
I: Integer;
begin
for I := 0 to Length(AMyArray) - 1 do
FreeAndNil( AMyArray[I] );
SetLength( AMyArray, 0 );
end;
function TMyObjectList<T>.ToArray: TArray<T>;
var
i: Integer;
begin
SetLength(Result, Count);
for i := 0 to Count - 1 do
Result[i] := Items[i];
end;
type
TMyItem = class
public
Data: string;
end;
List에 담을 Item 클래스를 하나 선언하고 테스트 코드를 넣어봤다.
자동 해제 옵션을 켜고 사용할때
procedure TForm2.Button2Click(Sender: TObject);
var
List: TMyObjectList<TMyItem>;
Item: TMyItem;
ItemArray: TArray<TMyItem>;
I: Integer;
begin
List := TMyObjectList<TMyItem>.Create;
Item := TMyItem.Create;
Item.Data := 'first item';
List.Add(Item);
Item := TMyItem.Create;
Item.Data := 'second item';
List.Add(Item);
ItemArray := List.ToArray;
for I := 0 to Length(ItemArray) - 1 do
ShowMessage(ItemArray[I].Data);
// 주의! 리스트가 해제될때 아이템도 같이 해제된다.
// Free한 이후에 ItemArray는 사용이 불가하다.
List.Free;
end;
자동 해제 옵션을 끄고 사용할때
procedure TForm2.Button1Click(Sender: TObject);
var
List: TMyObjectList<TMyItem>;
Item: TMyItem;
ItemArray: TArray<TMyItem>;
I: Integer;
begin
TMyItem = class
public
Data: string;
end;
List에 담을 Item 클래스를 하나 선언하고 테스트 코드를 넣어봤다.
자동 해제 옵션을 켜고 사용할때
procedure TForm2.Button2Click(Sender: TObject);
var
List: TMyObjectList<TMyItem>;
Item: TMyItem;
ItemArray: TArray<TMyItem>;
I: Integer;
begin
List := TMyObjectList<TMyItem>.Create;
Item := TMyItem.Create;
Item.Data := 'first item';
List.Add(Item);
Item := TMyItem.Create;
Item.Data := 'second item';
List.Add(Item);
ItemArray := List.ToArray;
for I := 0 to Length(ItemArray) - 1 do
ShowMessage(ItemArray[I].Data);
// 주의! 리스트가 해제될때 아이템도 같이 해제된다.
// Free한 이후에 ItemArray는 사용이 불가하다.
List.Free;
end;
자동 해제 옵션을 끄고 사용할때
procedure TForm2.Button1Click(Sender: TObject);
var
List: TMyObjectList<TMyItem>;
Item: TMyItem;
ItemArray: TArray<TMyItem>;
I: Integer;
begin
List := TMyObjectList<TMyItem>.Create(False);
Item := TMyItem.Create;
Item.Data := 'first item';
List.Add(Item);
Item := TMyItem.Create;
Item.Data := 'second item';
List.Add(Item);
ItemArray := List.ToArray;
// 생성할 때 AOwnsObjects 옵션을 False로 설정했기 때문에 List를 해제하더라도 Item은 해제되지 않는다.
List.Free;
for I := 0 to Length(ItemArray) - 1 do
ShowMessage(ItemArray[I].Data);
// Array의 사용을 마치면 배열을 해제하여 Item을 해제한다.
// 해제하기 전까지는 ItemArray를 계속 이용할 수 있다.
TMyObjectList<TMyItem>.FreeArray( ItemArray );
end;
Item := TMyItem.Create;
Item.Data := 'first item';
List.Add(Item);
Item := TMyItem.Create;
Item.Data := 'second item';
List.Add(Item);
ItemArray := List.ToArray;
// 생성할 때 AOwnsObjects 옵션을 False로 설정했기 때문에 List를 해제하더라도 Item은 해제되지 않는다.
List.Free;
for I := 0 to Length(ItemArray) - 1 do
ShowMessage(ItemArray[I].Data);
// Array의 사용을 마치면 배열을 해제하여 Item을 해제한다.
// 해제하기 전까지는 ItemArray를 계속 이용할 수 있다.
TMyObjectList<TMyItem>.FreeArray( ItemArray );
end;
예전에는 TObjectList를 이용하더라도 Item을 형변환해서 사용하거나 상속받아서 새로 만들고 했었는데 Generic을 이용하니 너무나 편하다.
C++의 Template가 이제 가물가물하니 시간내서 Delphi와 비교 좀 해봐야겠다.
'Programming > Delphi' 카테고리의 다른 글
Delphi - TOpenDialog쓰면서 FileExists로 왜 체크해요? (0) | 2010.03.14 |
---|---|
Delphi - TArray<T>의 Sort 및 BinarySearch (2) | 2010.02.22 |
Delphi - class의 private, protected에 strict를 추가해보자. (4) | 2010.01.29 |
Delphi - 클래스 내에 const 사용하기 (0) | 2010.01.27 |
[Delphi] Natural Order 문자열 정렬 (1) | 2009.08.14 |