Delphi 如何在泛型中实现TCollection和TCollectionItem功能

Delphi 如何在泛型中实现TCollection和TCollectionItem功能,delphi,generics,collections,delphi-xe6,Delphi,Generics,Collections,Delphi Xe6,我试图在泛型中实现TCollection和TCollectionItem功能。为了解决这个问题,我们需要对TGenericCollectionItem或TGenericCollection进行转发声明。实际的XE6 Delphi编译器不支持使用泛型类型的正向声明。如何制作。但是我们在为TCollectionItem分配所有者时仍然存在问题 E2010不兼容类型:“TGenericCollection”和“TGenericCollection” 如何解决此冲突?您需要的是以下代码: unit Ge

我试图在泛型中实现TCollection和TCollectionItem功能。为了解决这个问题,我们需要对TGenericCollectionItem或TGenericCollection进行转发声明。实际的XE6 Delphi编译器不支持使用泛型类型的正向声明。如何制作。但是我们在为TCollectionItem分配所有者时仍然存在问题

E2010不兼容类型:“TGenericCollection”和“TGenericCollection”


如何解决此冲突?

您需要的是以下代码:

unit Generics.Legacy;


{$WARN SYMBOL_DEPRECATED OFF} // we know that Added and Deleting are deprecated
{$HINTS OFF} // we know we have intentionally hidden some overridden methods


interface


uses
  Classes;


type
  TCollection<T: TCollectionItem> = class(TCollection)
  private
    procedure Added(var Item: TCollectionItem); overload; override;
    procedure Deleting(Item: TCollectionItem); overload; override;
    procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); overload; override;
    procedure SetItemName(Item: TCollectionItem); overload; override;
    procedure Update(Item: TCollectionItem); overload; override;
  protected
    procedure Added(var Item: T); reintroduce; overload; virtual; deprecated;
    procedure Deleting(Item: T); reintroduce; overload; virtual; deprecated;
    function GetItem(Index: Integer): T;
    procedure Notify(Item: T; Action: TCollectionNotification); reintroduce;
overload; virtual;
    procedure SetItem(Index: Integer; Value: T);
    procedure SetItemName(Item: T); reintroduce; overload; virtual;
    procedure Update(Item: T); reintroduce; overload; virtual;
  public
    type
      TCollectionEnumerator = class(Classes.TCollectionEnumerator)
      public
        function GetCurrent: T; inline;
        property Current: T read GetCurrent;
      end;


    constructor Create;
    function Add: T;
    function FindItemID(ID: Integer): T;
    function Insert(Index: Integer): T;
    function GetEnumerator: TCollection<T>.TCollectionEnumerator;
    property Items[Index: Integer]: T read GetItem write SetItem;
  end;


  TOwnedCollection<T: TCollectionItem> = class(TCollection<T>)
  private
    FOwner: TPersistent;
  protected
    function GetOwner: TPersistent; override;
  public
    constructor Create(AOwner: TPersistent);
  end;


implementation


{ TCollection<T> }
constructor TCollection<T>.Create;
begin
  inherited Create(T);
end;


function TCollection<T>.Add: T;
begin
  Result := T(inherited Add);
end;


procedure TCollection<T>.Added(var Item: T);
begin
end;


procedure TCollection<T>.Added(var Item: TCollectionItem);
begin
  Added(T(Item));
end;


procedure TCollection<T>.Deleting(Item: T);
begin
end;


procedure TCollection<T>.Deleting(Item: TCollectionItem);
begin
  Deleting(T(Item));
end;


function TCollection<T>.FindItemID(ID: Integer): T;
begin
  Result := T(inherited FindItemID(ID));
end;


function TCollection<T>.GetEnumerator: TCollection<T>.TCollectionEnumerator;
begin
  Result := TCollection<T>.TCollectionEnumerator.Create(Self);
end;


function TCollection<T>.GetItem(Index: Integer): T;
begin
  Result := T(inherited GetItem(Index));
end;


function TCollection<T>.Insert(Index: Integer): T;
begin
  Result := T(inherited Insert(Index));
end;


procedure TCollection<T>.Notify(Item: T; Action: TCollectionNotification);
begin
  inherited Notify(Item, Action);
end;


procedure TCollection<T>.Notify(Item: TCollectionItem; Action: TCollectionNotification);
begin
  Notify(T(Item), Action);
end;


procedure TCollection<T>.SetItem(Index: Integer; Value: T);
begin
  inherited SetItem(Index, Value);
end;


procedure TCollection<T>.SetItemName(Item: T);
begin
  inherited SetItemName(Item);
end;


procedure TCollection<T>.SetItemName(Item: TCollectionItem);
begin
  SetItemName(T(Item));
end;


procedure TCollection<T>.Update(Item: T);
begin
  inherited Update(Item);
end;


procedure TCollection<T>.Update(Item: TCollectionItem);
begin
  Update(T(Item));
end;


{ TCollection<T>.TCollectionEnumerator }
function TCollection<T>.TCollectionEnumerator.GetCurrent: T;
begin
  Result := T(inherited GetCurrent);
end;


{ TOwnedCollection<T> }
constructor TOwnedCollection<T>.Create(AOwner: TPersistent);
begin
  FOwner := AOwner;
  inherited Create;
end;


function TOwnedCollection<T>.GetOwner: TPersistent;
begin
  Result := FOwner;
end;


end.
我不知道这段代码的原始作者不是我,但我想它是不久前在Embarcadero论坛上发布的。
类似的实现可以在

中找到,泛型用于什么?您有一个非常规集合项的集合。泛型不需要这样做。
unit Generics.Legacy;


{$WARN SYMBOL_DEPRECATED OFF} // we know that Added and Deleting are deprecated
{$HINTS OFF} // we know we have intentionally hidden some overridden methods


interface


uses
  Classes;


type
  TCollection<T: TCollectionItem> = class(TCollection)
  private
    procedure Added(var Item: TCollectionItem); overload; override;
    procedure Deleting(Item: TCollectionItem); overload; override;
    procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); overload; override;
    procedure SetItemName(Item: TCollectionItem); overload; override;
    procedure Update(Item: TCollectionItem); overload; override;
  protected
    procedure Added(var Item: T); reintroduce; overload; virtual; deprecated;
    procedure Deleting(Item: T); reintroduce; overload; virtual; deprecated;
    function GetItem(Index: Integer): T;
    procedure Notify(Item: T; Action: TCollectionNotification); reintroduce;
overload; virtual;
    procedure SetItem(Index: Integer; Value: T);
    procedure SetItemName(Item: T); reintroduce; overload; virtual;
    procedure Update(Item: T); reintroduce; overload; virtual;
  public
    type
      TCollectionEnumerator = class(Classes.TCollectionEnumerator)
      public
        function GetCurrent: T; inline;
        property Current: T read GetCurrent;
      end;


    constructor Create;
    function Add: T;
    function FindItemID(ID: Integer): T;
    function Insert(Index: Integer): T;
    function GetEnumerator: TCollection<T>.TCollectionEnumerator;
    property Items[Index: Integer]: T read GetItem write SetItem;
  end;


  TOwnedCollection<T: TCollectionItem> = class(TCollection<T>)
  private
    FOwner: TPersistent;
  protected
    function GetOwner: TPersistent; override;
  public
    constructor Create(AOwner: TPersistent);
  end;


implementation


{ TCollection<T> }
constructor TCollection<T>.Create;
begin
  inherited Create(T);
end;


function TCollection<T>.Add: T;
begin
  Result := T(inherited Add);
end;


procedure TCollection<T>.Added(var Item: T);
begin
end;


procedure TCollection<T>.Added(var Item: TCollectionItem);
begin
  Added(T(Item));
end;


procedure TCollection<T>.Deleting(Item: T);
begin
end;


procedure TCollection<T>.Deleting(Item: TCollectionItem);
begin
  Deleting(T(Item));
end;


function TCollection<T>.FindItemID(ID: Integer): T;
begin
  Result := T(inherited FindItemID(ID));
end;


function TCollection<T>.GetEnumerator: TCollection<T>.TCollectionEnumerator;
begin
  Result := TCollection<T>.TCollectionEnumerator.Create(Self);
end;


function TCollection<T>.GetItem(Index: Integer): T;
begin
  Result := T(inherited GetItem(Index));
end;


function TCollection<T>.Insert(Index: Integer): T;
begin
  Result := T(inherited Insert(Index));
end;


procedure TCollection<T>.Notify(Item: T; Action: TCollectionNotification);
begin
  inherited Notify(Item, Action);
end;


procedure TCollection<T>.Notify(Item: TCollectionItem; Action: TCollectionNotification);
begin
  Notify(T(Item), Action);
end;


procedure TCollection<T>.SetItem(Index: Integer; Value: T);
begin
  inherited SetItem(Index, Value);
end;


procedure TCollection<T>.SetItemName(Item: T);
begin
  inherited SetItemName(Item);
end;


procedure TCollection<T>.SetItemName(Item: TCollectionItem);
begin
  SetItemName(T(Item));
end;


procedure TCollection<T>.Update(Item: T);
begin
  inherited Update(Item);
end;


procedure TCollection<T>.Update(Item: TCollectionItem);
begin
  Update(T(Item));
end;


{ TCollection<T>.TCollectionEnumerator }
function TCollection<T>.TCollectionEnumerator.GetCurrent: T;
begin
  Result := T(inherited GetCurrent);
end;


{ TOwnedCollection<T> }
constructor TOwnedCollection<T>.Create(AOwner: TPersistent);
begin
  FOwner := AOwner;
  inherited Create;
end;


function TOwnedCollection<T>.GetOwner: TPersistent;
begin
  Result := FOwner;
end;


end.