自作クラス作成Tips ー 自作クラスにレコード型のプロパティを持たせる時の注意
自作クラスにレコードプロパティを実装したいという場面は結構あるはずです。
ただ、実装時にはいくつか注意しなければならないことがあります。
レコードプロパティのメンバに代入するときの問題
例えば次のような実装の時
TTsrRec = record Name : string; No : Integer; end; TTscData = class(TObject) private FRec : TTsrRec; published property Rec : TTsrRec read FRec write FRec; end;
TTscDataクラスのRecプロパティに値を書き込みたい場合、どうなるでしょうか。
procedure TForm3.FormCreate(Sender: TObject); var data : TTscData; begin data := TTscData.Create; data.Rec.Name := 'Test'; data.Rec.No := 1; end;
実はこれ、コンパイルできません。
E2064エラーがでます。代入できないんですね。
上のような実装をした場合、これに値を書き込みたい場合はこうなります。
procedure TForm3.FormCreate(Sender: TObject); var data : TTscData; rec : TTsrRec; begin rec.Name := 'Test'; rec.No := 1; data := TTscData.Create; data.Rec := rec; end;
実装内容や仕様によっては、この使い方でも問題ないでしょうが
できればレコードのメンバに直接書き込みたいなと思うことも多いでしょう。
ではどうすればいいのか。
レコードを拡張すればいいんです。
Delphiのレコード型はクラス方のような実装ができます。
レコードにプロパティを用意する
レコードの実装を少々変更しました。
type TTsrRec = record private FName : string; FNo : Integer; procedure SetName(name:string); procedure SetNo(no:integer); public property Name : string read FName write SetName; property No : Integer read FNo write SetNo; end; implementation procedure TTsrRec.SetName(name:string); begin FName := name; end; procedure TTsrRec.SetNo(no:Integer); begin FNo := no; end;
プロパティメソッドを実装し、レコードのメンバに書き込みをする場合はそれぞれSetName、SetNoプロシージャが呼び出されます。
このような実装をすると、レコードのメンバに直接値を書き込めるようになります。
見てのとおり、レコード型はクラスのような実装ができ、なんならイベントの実装とかも普通にできます。じゃぁ、クラスと何が違うんやというと。
- レコードからの継承はできない
- レコードは可変部分を持てる
- レコードは値型、クラスは参照型
- レコードはコンストラクタを使って自動生成されるが、クラスは明示的に生成する
- レコードのコンストラクタはデフォルトの引数なしがあるため、ユーザー定義のコンストラクタには引数が1つ以上必要
- レコードはデストラクタを持てない
- 継承に対応しないので、当然virtualやdynamicなんかもサポートしない。
- レコードはWin32プラットフォームでインターフェースを実装できない
と、こんなところです。
特に継承できるのか否かは大きいと思います。
なので、どちらで実装するかはケースバイケースでって感じで。
ディスカッション
コメント一覧
まだ、コメントがありません