RTTI - 为什么在某些情况下 TTypedData.CompType 为零?

RTTI - why is in some cases TTypedData.CompType nil?

我有一个 TValue 附上一组。 TTypedData.CompType 为零。所以调用 TValue.ToString 会抛出异常,因为 System.TypInfo.SetToString 假定 CompType 永远不会为零。

为什么某些集合类型 CompType 为 nil?

TTestEnumType = (tstEnum1 = 1, tstEnum2 = 2, tstEnum3 = 3, tstEnum4 = 4, tstEnum5 = 5, tstEnum6 = 6, tstEnum7 = 7);
TTestEnumTypeSet = set of TTestEnumType;
TTestSetOfByte = set of Byte;

上面我们定义了两个集合类型:TTestEnumTypeSetTTestSetOfByte

下面的简单测试表明 CompType 对于 TTestSetOfByte 为零。

procedure TTestUtlRttiComparer.TestSetToString;
var
  TypeData1: TTypeData;
  TypeData2: TTypeData;
  TypeInfo1: TTypeInfo;
  TypeInfo2: TTypeInfo;
begin
  TypeInfo1 := PTypeInfo(TypeInfo(TTestSetOfByte))^;
  TypeInfo2 := PTypeInfo(TypeInfo(TTestEnumTypeSet))^;
  CheckTrue(TypeInfo1.Kind = tkSet);
  CheckTrue(TypeInfo2.Kind = tkSet);

  TypeData1 := GetTypeData(@TypeInfo1)^;
  TypeData2 := GetTypeData(@TypeInfo2)^;
  CheckTrue(Assigned(TypeData1.CompType));
  CheckTrue(Assigned(TypeData2.CompType), 'TypeData2.CompType is NULL!!!! WHY??????'); // this FAILS!!!
end;

具有显式分配序数的枚举类型没有 RTTI。这在 documentation:

中说明

Enumerated constants without a specific value have RTTI:

type SomeEnum = (e1, e2, e3);

whereas enumerated constants with a specific value, such as the following, do not have RTTI:

type SomeEnum = (e1 = 1, e2 = 2, e3 = 3);