在德尔福,如果我有一个TValue
反映未知对象的实例,如何测试该对象是否是任何类型泛型的实例TEnumerable<>
(或者甚至更好,也which它是特定通用枚举类型的实例,例如TList<>
)?
注意:我已经知道如何轻松检查其exact类型,即与.BaseType
对应的属性TRttiType
of the TValue
,例如导致TList<string>
,但我想测试的是它是否是TList<>
of any子项类型.
为了举例说明这个假设代码“IsAnyKindOfGenericEnumerable()”的工作原理,下面是一些示例代码:
var
LContext : TRttiContext;
obj_1_rtti_value : TValue;
obj_2_rtti_value : TValue;
obj_3_rtti_value : TValue;
obj_1_rtti_type : TRttiType;
obj_2_rtti_type : TRttiType;
obj_3_rtti_type : TRttiType;
LContext := TRttiContext.Create();
{
...
obj_1_rtti_value is set to a TValue reflection of a TList<string> object here
obj_2_rtti_value is set to a TValue reflection of a plain TObject object here
obj_3_rtti_value is set to a TValue reflection of a TQueue<integer> object here
...
}
obj_1_rtti_type := LContext.GetType(obj_1_rtti_value.TypeInfo);
obj_2_rtti_type := LContext.GetType(obj_2_rtti_value.TypeInfo);
obj_3_rtti_type := LContext.GetType(obj_3_rtti_value.TypeInfo);
IsAnyKindOfGenericEnumerable(obj_1_rtti_type); //Would return true
IsAnyKindOfGenericEnumerable(obj_2_rtti_type); //Would return false
IsAnyKindOfGenericEnumerable(obj_3_rtti_type); //Would return true
再说一次,最好的事情是如果我也能检测到which有点儿TEnumerable<>
输入它,例如:
IsAnyKindOfGenericEnumerable(obj_1_rtti_type); //Will return true + `TList<>`
IsAnyKindOfGenericEnumerable(obj_2_rtti_type); //Will return false
IsAnyKindOfGenericEnumerable(obj_3_rtti_type); //Will return true + `TQueue<>`
我努力了:
if obj_1_rtti_type is TRttiEnumerationType then
begin
//...
end;
但由于某种原因,这评估为false
,我完全不知道这是为什么?表达方式value_type.BaseType.Name
确实评估为'TEnumerable<System.string>'
在这种情况下,但为了实现我的目标,除了手动解析该字符串之外,确实必须有其他方法,对吧?
最后,必须仅使用 RTTI 信息来实现目标,即不允许通过引用 TValue 背后的真实对象进行任何“作弊”(出于本问题范围之外的原因)。