トップ «前の日記(2004-02-19(Thu)) 最新 次の日記(2004-02-21(Sat))» 編集

K2さんの雑記


2004-02-20(Fri) [長年日記]

[Delphi]Assign使ってますか(1)

VCLのTPersistentクラスには、Assignというメソッドがpublicで宣言されている。この中身をそのまま使うと例外が上がるだけである。よってTPersistent継承クラスを作った場合は、Assign*1をoverrideして、再定義する。

例えば、TItemをTPersistentから継承する場合を考えてみよう。インターフェイス定義は以下のようになる。

TItem = class(TPersistent)
private
  FName: string;
  procedure SetName(const Value: string);
public
  procedure Assign(Source: TPersistent); override;
  property Name: string read FName write SetName;
end;

TItemはNameプロパティを持っている。通常は、もっとたくさんのプロパティを持つことになるだろう。たとえばファイルを扱うクラスなら、Filename、Date、Sizeなんかが思いつく。URLを扱うクラスなら、URLそのものやCheckDateなど。ここでは、簡単にするためにNameだけを持つItemクラスだと考える。

実装部は以下のようになる。

procedure TItem.Assign(Source: TPersistent);
begin
  if Source is TItem then
  begin
    Name := TItem(Source).Name;
  end
  else
    inherited Assign(Source);
end;
procedure TItem.SetName(const Value: string);
begin
  FName := Value;
end;

SetNameメソッドは、Delphiが作るスケルトンそのままである。Assignの方だが、まず渡されたSourceがTItemかどうか調べる。TItemじゃない場合は、inheritedしてTPersistentのAssignを呼び出し、例外を上げる。

渡されたSourceがTItemの場合は、プロパティのコピーを行う。TItemはNameしか持たないので、ここではNameだけをコピーしている。

こう定義されたTItemは、以下のように使う。

var
  Item1, Item2: TItem;
begin
  Item1 := TItem.Create;
  try
    Item1.Name := 'Item1の名前';
    Item2 := TItem.Create;
    try
      // Item1の中身をItem2にコピー
      Item2.Assign(Item1);
      ShowMessage(Item2.Name);
    finally
      Item2.Free;
    end;
  finally
    Item1.Free;
  end;
end;

これでアイテムの中身がコピーできる。

一見、「なーんだ」という感じのする方法論であるが、オブジェクト指向で使う具体的な方法論のほとんどは、「なーんだ」という手法の組み合わせである。しかし、その有効性は高い。

デザインパターン等では、Cloneという、自分のクローンを作成してオブジェクトを返すメソッドが出てくるが、VCLではCloneはなくAssignを使用している。個人的にはAssignの方が利用できる効果が高いと感じている。

さて、時間となった。Assignをどういう場面で活用していくかは、またの機会に。

*1 またはAssignToをoverrideしてもよいが、ここではAssignをそのままoverrideすることとして話を進める

[BIKE]ベルト切断

3回目。1.7cm。


1965|09|
2002|09|10|11|12|
2003|01|02|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|03|04|05|08|
2014|01|02|03|04|05|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|11|
2017|01|03|05|06|07|08|10|11|12|
2018|01|02|03|04|05|08|09|10|12|
2020|01|07|




2004年
2月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29
//
自己紹介
自己紹介
広告
計るだけダイエット
つっこみリスト
TrackBacks
日記仲間
/ / /
最近の日記