代码之家  ›  专栏  ›  技术社区  ›  mghie

Delphi2009泛型编译问题

  •  2
  • mghie  · 技术社区  · 17 年前

    下面的代码没有编译,我一点也不知道为什么它给了我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 回复  |  直到 15 年前
        1
  •  6
  •   Barry Kelly    17 年前

    如果T是一个字符串呢?如果是TSize唱片呢?

    如果不约束T(例如,使用<T:class>),则无法确定比较是否有意义。

    相反,如果您想比较两个T类型的值,可以使用泛型。默认单位和使用:

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

    比较T型的x值和y值。

        2
  •  3
  •   Angus Glashier    17 年前

    不能将运算符与非类型泛型一起使用。看见 here 进行讨论。

    如果将其更改为:

    TPrimaryKey<T: class> = class(TObject)
    
        3
  •  2
  •   Steve    17 年前

    我认为最初的海报试图围绕简单类型(Integer、double等)创建一个对象包装器,因此将T约束到类可能无法满足他的需要。

        4
  •  1
  •   Toon Krijthe    17 年前

    编译器很难确定两个“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;