santiagoIT
santiagoIT

Reputation: 9421

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

I have a TValue enclosing a set. TTypedData.CompType is nil. So calling TValue.ToString throws an exception, because System.TypInfo.SetToString assumes CompType to never be nil.

Why is CompType nil for some set types?

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

Above we have defined two set types: TTestEnumTypeSet and TTestSetOfByte.

The following simple test shows that CompType is nil for 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;

Upvotes: 2

Views: 141

Answers (1)

David Heffernan
David Heffernan

Reputation: 612784

Enumerated types with explicitly assigned ordinality do not have RTTI. This is stated in the 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);

Upvotes: 4

Related Questions