2

私は Delphi 2009 Trial をチェックしていますが、すぐにジェネリック関連の問題に遭遇します。

次のコードはコンパイルされず、Equals() メソッドで E2015 が返される理由がまったくわかりません。

type
  TPrimaryKey<T> = class(TObject)
  strict private
    fValue: T;
  public
    constructor Create(AValue: T);
    function Equals(Obj: TObject): boolean; override;
    function GetValue: T;
  end;

constructor TPrimaryKey<T>.Create(AValue: T);
begin
  inherited Create;
  fValue := AValue;
end;

function TPrimaryKey<T>.Equals(Obj: TObject): boolean;
begin
  Result := (Obj <> nil) and (Obj is TPrimaryKey<T>)
    and (TPrimaryKey<T>(Obj).GetValue = fValue);
end;

function TPrimaryKey<T>.GetValue: T;
begin
  Result := fValue;
end;

fValue と GetValue() の結果を比較できないとコンパイラが判断するのはなぜですか?

4

4 に答える 4

6

Tが文字列の場合はどうなりますか?TSizeレコードの場合はどうなりますか?

Tを制約しないと(たとえば、<T:class>を使用)、比較が意味のあるものになるかどうかを確認することはできません。

代わりに、タイプTの2つの値を比較する場合は、Generics.Defaults単位を使用して、次を使用できます。

TEqualityComparer<T>.Default.Equals(x, y)

タイプTの値xとyを比較します。

于 2008-11-06T23:57:37.340 に答える
3

型指定されていないジェネリックで演算子を使用することはできません。ディスカッションについては、こちらを参照してください。

次のように変更するとコンパイルされます。

TPrimaryKey<T: class> = class(TObject)
于 2008-11-06T23:37:58.020 に答える
2

元のポスターは単純な型(整数、倍精度など)の周りにオブジェクトラッパーを作成しようとしていると思います。そのため、TをClassに制約しても、おそらく彼が望むものには機能しません。

于 2008-11-06T23:46:51.747 に答える
1

コンパイラは、両方の「T」が同じであると判断するのに問題があります。しかし、ちょっとしたトリックでそれを機能させることができます:

type
  TPrimaryKey<T> = class(TObject)
  public
    type
      TCompare<T1> = reference to function(const A1, A2: TPrimaryKey<T1>): Boolean;
  private
    fValue: T;
    fCompare : TCompare<T>;
  public
    constructor Create(AValue: T; ACompare: TCompare<T>);
    function Equals(Obj: TPrimaryKey<T>): Boolean; reintroduce;
    function GetValue: T;
    function CreateNew(const AValue: T): TPrimaryKey<T>;

  end;

constructor TPrimaryKey<T>.Create(AValue: T; ACompare: TCompare<T>);
begin
  inherited Create;
  fValue := AValue;
  fCompare := ACompare;
end;

function TPrimaryKey<T>.Equals(Obj: TPrimaryKey<T>): Boolean;
begin
  Result := FCompare(self, Obj);
end;

function TPrimaryKey<T>.GetValue: T;
begin
  Result := fValue;
end;

function TPrimaryKey<T>.CreateNew(const AValue: T): TPrimaryKey<T>;
begin
  Result := TPrimaryKey<T>.Create(AValue, FCompare);
end;

あなたはそれを次のようにインスタンス化します:

var
  p1, p2 : TPrimaryKey<Integer>;
begin
  p1 := TPrimaryKey<Integer>.Create(10,
    function(const A1, A2: TPrimaryKey<Integer>): Boolean
    begin
      Result := (A1<>nil) and (A2<>nil) and (A1.GetValue=A2.GetValue);
    end);
  p2 := p1.CreateNew(10);

  p1.Equals(p2);
end;
于 2008-11-06T23:48:39.463 に答える