Delphiは、ジェネリッククラスのコードを複製するという厄介な習慣を持っています。たとえそのコードが本当に同じであっても、ジェネリック型は似ているからです。
異なるクラスを格納するための重複を避けたい。
私のジェネリックコンテナでは、必要な場合にのみFree
を使用します。汎用クラスの生成コードの重複を防ぐにはどうすればよいですか?
は、私はそうのような汎用コンテナがあるとします。
unit Unit1;
interface
uses Generics.Collections;
type
TMyContainer<T> = class(TObject)
strict private
FData: TList<T>;
public
constructor Create; virtual;
end;
私はT
は、多くの場合、オブジェクトになります知っています。すべてのオブジェクトは実際にはTObject
なので、私のコンテナにはさまざまなタイプのオブジェクトに対して重複した汎用コードを作成したくありません。
次のトリックは重複を防ぐために機能しますか?
A-クラス関数とコンストラクタを代入:
unit Unit2;
uses Unit1;
type
TMyContainer<T> = class(Unit1.TMyContainer<T>)
public
class function Create: TMyContainer<T>; static;
end;
B:そうようなクラスの機能Create
を実装:
class function TMyContainer<T>.Create: TMyContainer<T>;
var
X: TObject;
begin
if GetTypeKind(T) = tkClass then begin
X:= Unit1.TMyContainer<TObject>.Create;
end else begin
X:= Unit1.TMyContainer<T>.Create;
end;
TObject(Result):= X;
end;
このトリック作業が重複するコードを生成するから、コンパイラを防ぐために、ウィル私は間違った仮定を使用しているため、これは失敗しますか?
私は自分のデータに非ジェネリックストアを使用することに頼らないことに注意してください。
完全なサンプルコードは、以下の
unit Unit49;
interface
uses Generics.Collections;
type
TMyContainer<T> = class(TObject)
strict private
FData: TList<T>;
public
constructor Create; virtual;
end;
implementation
constructor TMyContainer<T>.Create;
begin
inherited Create;
FData:= TList<T>.Create;
end;
end.
サンプル・プログラムこのトリックの作品は、オブジェクトの種類ごとに コードを複製生成するから、コンパイラを防ぐためだろう
program Project85;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Unit49 in 'Unit49.pas';
type
TMyContainer<T> = class(Unit49.TMyContainer<T>)
public
class function Create: TMyContainer<T>; static;
end;
{ TMyContainer<T> }
class function TMyContainer<T>.Create: TMyContainer<T>;
var
Y: T;
X: TObject;
begin
if GetTypeKind(T) = tkClass then begin
X:= Unit49.TMyContainer<TObject>.Create;
end else begin
X:= Unit49.TMyContainer<T>.Create;
end;
TObject(Result):= X;
end;
var
A: TMyContainer<TObject>;
B: TMyContainer<TLanguages>;
begin
A:= TMyContainer<TObject>.Create;
B:= TMyContainer<TLanguages>.Create;
readln;
end.
私はとにかくだけでなく、ポート自体がないレガシーコード.... – Johan
を持っているので、私は認識トリックが最近Generics.Collectionsに例示されていると思います。私はXE7に対してXE8の差分を読んでいました。 Spring4dも同様のことを考えています。 –
OK、私はそれをチェックアウトします。 – Johan