【发布时间】:2014-10-18 11:53:51
【问题描述】:
我正在尝试为通用列表定义我自己的项目类型。所有项目都需要有一个owner 属性。
type
TGenericCollection<TGenericCollectionItem: class> = class(TObjectList<TGenericCollectionItem>)
protected
procedure Notify(const Value: TGenericCollectionItem; Action: TCollectionNotification); override;
public
procedure Assign(Source: TGenericCollection<TGenericCollectionItem>); virtual;
end;
TGenericCollectionItem = class
private
FOwner: TGenericCollection<TGenericCollectionItem>; //another class can change this value if it was declared in the same unit
protected
function GetOwner: TGenericCollection<TGenericCollectionItem>; virtual;
public
constructor Create; virtual;
property Owner: TGenericCollection<TGenericCollectionItem> read GetOwner;
end;
implementation
{ TGenericCollection<TGenericCollectionItem> }
procedure TGenericCollection<TGenericCollectionItem>.Assign(
Source: TGenericCollection<TGenericCollectionItem>);
begin
AddRange(Source.ToArray);
end;
procedure TGenericCollection<TGenericCollectionItem>.Notify(
const Value: TGenericCollectionItem; Action: TCollectionNotification);
begin
inherited;
if (Action = cnAdded) then
begin
OutputDebugString(PChar(Value.ClassName)); // Debug Output: THandingItem Process GenericCollection.exe (2424)
OutputDebugString(PChar(Self.ClassName)); // Debug Output: THandingList Process GenericCollection.exe (2424)
// Value.FOwner := Self; // Error: [dcc32 Error] Unit2.pas(46): E2003 Undeclared identifier: 'FOwner'
// (Value as TGenericCollectionItem).FOwner := Self; // Error: [dcc32 Error] Unit2.pas(46): E2003 Undeclared identifier: 'FOwner'
// (Value as TGenericCollectionItem<T>).FOwner := Self; // Undeclared identifier 'T'
end;
end;
当我尝试更改 FOwner 值时,编译器会说 FOwner 是未声明的标识符。 THandingList 继承自 TGenericCollection。 THandingItem 继承自 TGenericCollectionItem。
我做错了什么? Sample project
UPD:TGenericCollectionItem 已在代码示例中更改。
控制台应用:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Generics.Collections;
type
TGenericCollection<TGenericCollectionItem: class> = class(TObjectList<TGenericCollectionItem>)
protected
procedure Notify(const Value: TGenericCollectionItem; Action: TCollectionNotification); override;
end;
TGenericCollectionItem = class
public
Owner: TGenericCollection<TGenericCollectionItem>;
end;
procedure TGenericCollection<TGenericCollectionItem>.Notify(
const Value: TGenericCollectionItem; Action: TCollectionNotification);
begin
inherited;
if (Action = cnAdded) then
Value.Owner := Self;
end;
var
GenericCollectionItem: TGenericCollectionItem;
GenericCollection: TGenericCollection<TGenericCollectionItem>;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
GenericCollection := TGenericCollection<TGenericCollectionItem>.Create;
try
GenericCollectionItem := TGenericCollectionItem.Create;
GenericCollection.Add(GenericCollectionItem);
finally
GenericCollection.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
【问题讨论】:
-
那是因为您在
TGenericCollectionItem<T: class>类中声明了FOwner,而不是在基类TGenericCollectionItem中(尚不知道)。此外,它目前是只读的。 -
TGenericCollectionItem 的通用参数是什么意思?当然这是错误的。你的设计还有一个致命的缺陷。一个项目可以是两个列表的成员。楼主是谁?
-
@TLama 好的。我已经更改了
TGenericCollectionItem类(请参阅有问题的代码)。但是编译器还是这么说的。 -
@DavidHeffernan 我不知道谁将成为所有者。可能是最后一个。我正在尝试在泛型中实现
TCollection和TCollectionItem功能。TCollection和TCollectionItem在System.Classes单元中。 -
@DavidHeffernan 检查问题更新。
标签: delphi generics delphi-xe6