Be aware of the “Growth by Generics”
Another scenario that might depend on your application code and cause an increase of the memory used by the compiler and the debugger relates with the way generic data types are used. The way the Object Pascal compiler works can cause the generation of many different types based on the same generic definition,at times even totally identical types that are compiled in different modules. While we won’t certainly suggest removing generics,quite the contrary,there are a few options to consider:
- Try to avoid circular unit references for units defining core generic types
- Define and use the same concrete type definitions when possible
- If possible,refactor generics to share code in base classes,from which a generic class inherits
我理解的最后一个项目前两个我不太清楚.
例如,考虑第二项,如果我声明TList< Integer>在两个单独的单元中,我可以在我的可执行文件中的每个单元中获得两个独立的代码块?我当然希望不要!
解决方法
泛型人群指的是具有完整的TList< T>即使底层生成的代码相同,您也可以使用每种特定类型的副本.
例如:TList< TObject>和TList< TPersistent>将包括TList< T>的两个单独副本.即使生成的代码可以折叠成单个代码.
这将我们移动到第3点,其中使用基类为普通类代码,然后在其上使用泛型类来获取类型安全性,可以在编译期间和在exe文件中节省内存.
例如,在非通用TObjectList之上构建泛型类只会包含每个特定类型的精简通用层,而不是完整的TObjectList功能.报告为QC 108966
TXObjectList<T: class,constructor> = class(TObjectList) protected function GetItem(index: Integer): T; procedure SetItem(index: Integer; const Value: T); public function Add: T; property Items[index: Integer]: T read GetItem write SetItem; default; end; function TXObjectList<T>.GetItem(index: Integer): T; begin Result := T( inherited GetItem(index)); end; procedure TXObjectList<T>.SetItem(index: Integer; const Value: T); begin inherited SetItem(index,Value); end; function TXObjectList<T>.Add: T; begin Result := T.Create; inherited Add(Result); end;