TStringListをレコードにラップする
-
06-07-2019 - |
質問
テキスト操作にDelphiのTStringListを使用する傾向があるため、次のような多くのプロシージャ/関数を記述します。
var
TempList: TStringList;
begin
TempList:= TStringList.Create;
try
// blah blah blah do stuff with TempList
finally
TempList.Free;
end;
end;
このような一般的なユーティリティクラスの作成と解放を削除するとよいでしょう。
メソッドを持つレコードがあるので、TStringListのようなクラスをラップすることは可能ですか? 次のように記録します:
var
TempList: TRecordStringList;
begin
// blah blah blah do stuff with TempList
end;
解決
それは可能です。必要なメソッド/オブジェクトを公開するインターフェイスを作成します。
type
IStringList = interface
procedure Add(const s: string); // etc.
property StringList: TStringList read GetStringList; // etc.
end;
インターフェースを実装し、実際の TStringList
をラップする:
type
TStringListImpl = class(TInterfacedObject, IStringList)
private
FStringList: TStringList; // create in constructor, destroy in destructor
// implementation etc.
end;
レコードを実装します:
type
TStringListRecord = record
private
FImpl: IStringList;
function GetImpl: IStringList; // creates TStringListImpl if FImpl is nil
// returns value of FImpl otherwise
public
procedure Add(const s: string); // forward to GetImpl.Add
property StringList: TStringList read GetStringList; // forward to
// GetImpl.StringList
// etc.
end;
レコード内にインターフェイスがあるという事実は、コンパイラが参照カウントを自動的に処理し、コピーが作成および破棄されるときに_AddRefおよび_Releaseを呼び出すため、ライフタイム管理が自動的に行われることを意味します。これは、自分自身への参照を決して含まない(サイクルを作成する)オブジェクトに対して機能します。参照グラフでサイクルを乗り越えるには、参照カウントにさまざまなトリックが必要です。
他のヒント
Delphi 2009にアップグレードできた場合は、 Barryのスマートポインターの動作。
TSmartPointer<T: class> = record
strict private
FValue: T;
FLifetime: IInterface;
public
constructor Create(const AValue: T); overload;
class operator Implicit(const AValue: T): TSmartPointer<T>;
property Value: T read FValue;
end;
これらは非常に優れていますが、GenericsおよびAnonymousメソッドが必要です。 Delphi 2009 にアップグレードしていない場合は、今すぐアップグレードしてください。特に、 BOGOスペシャルを提供しています。また、 Delphi開発者ハンドブック 無料も入手できます。 >試用版のダウンロード。私もすでにそのコピーを購入しました。
もう1つの例があります CCで実装。
StringListは、値であることを除いてTStringListと同じです タイプ。作成、破棄、または配置する必要はありません 試してください/最終的に。これはコンパイラーによって行われます。がある これらが機能するための実質的な特別なパフォーマンスペナルティはありません。
var strings: StringList; astr: string; begin strings.Add('test1'); strings.Add('test2'); aStr := string(strings); RichEdit.Lines.AddStrings(strings); end;
コードをテンプレートとして使用して、TObjectを値クラス型としてラップできます。
すでにTStringListのすべてが公開されています。