Delphi泛型TObjectList继承
我想创建一个TObjectList< T>后代来处理我的应用程序中的对象列表之间的常见功能.然后我想进一步从新类继续下载,以便在需要时引入其他功能.我似乎无法使用超过1级的继承.我可能需要更多地了解泛型,但是我搜索高低都是正确的方法来做到这一点而没有成功.到目前为止,这是我的代码:
unit edGenerics; interface uses Generics.Collections; type TObjectBase = class public procedure SomeBaseFunction; end; TObjectBaseList<T: TObjectBase> = class(TObjectList<T>) public procedure SomeOtherBaseFunction; end; TIndexedObject = class(TObjectBase) protected FIndex: Integer; public property Index: Integer read FIndex write FIndex; end; TIndexedObjectList<T: TIndexedObject> = class(TObjectBaseList<T>) private function GetNextAutoIndex: Integer; public function Add(AObject: T): Integer; function ItemByIndex(AIndex: Integer): T; procedure Insert(AIndex: Integer; AObject: T); end; TCatalogueItem = class(TIndexedObject) private FID: integer; public property ID: integer read FId write FId; end; TCatalogueItemList = class(TIndexedObjectList<TCatalogueItem>) public function GetRowById(AId: Integer): Integer; end; implementation uses Math; { TObjectBase } procedure TObjectBase.SomeBaseFunction; begin end; { TObjectBaseList<T> } procedure TObjectBaseList<T>.SomeOtherBaseFunction; begin end; { TIndexedObjectList } function TIndexedObjectList<T>.Add(AObject: T): Integer; begin AObject.Index := GetNextAutoIndex; Result := inherited Add(AObject); end; procedure TIndexedObjectList<T>.Insert(AIndex: Integer; AObject: T); begin AObject.Index := GetNextAutoIndex; inherited Insert(AIndex,AObject); end; function TIndexedObjectList<T>.ItemByIndex(AIndex: Integer): T; var I: Integer; begin Result := Default(T); while (Count > 0) and (I < Count) and (Result = Default(T)) do if Items[I].Index = AIndex then Result := Items[I] else Inc(I); end; function TIndexedObjectList<T>.GetNextAutoIndex: Integer; var I: Integer; begin Result := 0; for I := 0 to Count - 1 do Result := Max(Result,Items[I].Index); Inc(Result); end; { TCatalogueItemList } function TCatalogueItemList.GetRowById(AId: Integer): Integer; var I: Integer; begin Result := -1; for I := 0 to Pred(Self.Count) do if Self.Items[I].Id = AId then begin Result := I; Break; end; end; end. /////// ERROR HAPPENS HERE ////// ???? why is beyond me 看来,以下声明: >>> TCatalogueItemList = class(TIndexedObjectList<TCatalogueItem>) <<<< 导致以下编译器错误:
然而,编译器在编译单元的END处显示错误(第106行),而不是在声明本身上显示错误,这对我没有任何意义…… 基本上我的想法是我有一个从TObjectList开始的通用列表,我可以根据需要扩展新功能.对此有任何帮助将是伟大的! 我应该使用Delphi 2010添加. 谢谢. 解决方法
您的错误是在类型转换中,编译器错误是正常的(但它无法在我的Delphi XE3中找到正确的文件).
您的ItemByIndex方法被声明: TIndexedObjectList<T>.ItemByIndex(AIndex: Integer): T; 但是你有这条线: Result := TIndexedObject(nil); 这对于父类TIndexedObjectList来说很好,其中函数的结果是TIndexedObject类型,但对于后代类TCatalogueItemList则不行,其中函数的结果是TCatalogueItem类型. 您可能知道,TCatalogueItem实例与TIndexedObject变量兼容,但反之则不然.它翻译成这样的东西: function TCatalogueItemList.ItemByIndex(AIndex: Integer): TCatalogueItem; begin Result := TIndexedObject(nil); //did you see the problem now? 要将结果初始化为nil值,可以调用Default()伪函数,如下所示: Result := Default(T); 在Delphi XE或更高版本中,该解决方案也是通用的.您可以使用T类型应用泛型类型转换,而不是将结果类型转换为固定的TIndexedObjectList类 Result := T(nil); //or Result := T(SomeOtherValue); 但是,在这种特定情况下,不需要类型转换nil常量,因为nil是一个特殊值,它与任何引用赋值兼容,所以你只需要用以下代码替换: Result := nil; 它会编译,并希望按预期工作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |