[英]Delphi: RTTI and TObjectList<TObject>
根据之前一篇文章的一个答案,我正在研究以下设计的可能性
TChildClass = class(TObject)
private
FField1: string;
FField2: string;
end;
TMyClass = class(TObject)
private
FField1: TChildClass;
FField2: TObjectList<TChildClass>;
end;
现在,在现实世界中,TMyClass将有10个不同的列表,所以我希望能够使用RTTI解决这些列表。 但是,我对这个类的其他字段不感兴趣,所以我需要检查某个字段是否是某种TObjectList。 这是我到目前为止所得到的:
procedure InitializeClass(RContext: TRttiContext; AObject: TObject);
var
ROwnerType: TRttiType;
RObjListType: TRttiType;
RField: TRttiField;
SchInf: TSchemaInfoDetail;
begin
ROwnerType := RContext.GetType(AObject.ClassInfo);
RObjListType := RContext.GetType(TObjectList<TObject>);
for RField in ROwnerType.GetFields do begin
// How do I check if the type of TMyClass.FField2 (which is TObjectList<TChildClass>) is some sort of TObjectList?
end;
显然, RField.FieldType <> RObjListType.FieldType
。 但是,他们确实有一些关系,不是吗? 为了使RField.FieldType
实际上是一个TObjectList
非常可能,对一般功能进行非常精细的检查似乎很糟糕(而且错误!)。
说实话,我对泛型非常不舒服,所以这个问题可能很天真。 但是,我非常乐意学习。 以上解决方案是否可以实施? TIA!
每个通用实例化都是唯一的,并且与RTTI的其他实例化无关。 因为Delphi无法在运行时实例化泛型类型,所以没有相当于.NET的GetGenericTypeDefinition
。 你能做的最好的就是查看类型的形状 - 例如它是否实现了GetEnumerator
, Add
等。
这也可以足够灵活地处理常规集合类型,而不仅仅是从TObjectList<T>
实例化的类型。 C#与其集合初始化器类似 - 它查找Add
方法并向其插入调用:
Delphi可以在运行时实例化泛型类型。 问题是,泛型类型通常不包含在运行时信息中。 如果您持有特定类型的全局变量(在您的情况下为TObjectList <TChildClass>),则在初始化部分中实例化(并释放)该特定类的运行时信息将不会被链接器剥离,您将能够实例化它以后动态地。 (您需要为context.findType()提供类的完全限定名称才能正常工作。)我花了一些时间来弄清楚如何做到这一点我对它肯定不满意,但是因为我还没有找到另一种方法我现在必须处理它。 如果有人知道更好的方法让我知道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.