This is going to be a short one. Just wanted to share a simple and elegant work-around for this QC issue:
type TypeOf<T> = record class function TypeInfo: PTypeInfo; static; class function Name: string; static; class function Kind: TTypeKind; static; end; { TypeOf<T> } class function TypeOf<T>.Kind: TTypeKind; var LTypeInfo: PTypeInfo; begin LTypeInfo := TypeInfo; if LTypeInfo <> nil then Result := LTypeInfo^.Kind else Result := tkUnknown; end; class function TypeOf<T>.Name: string; var LTypeInfo: PTypeInfo; begin LTypeInfo := TypeInfo; if LTypeInfo <> nil then Result := GetTypeName(LTypeInfo) else Result := ''; end; class function TypeOf<T>.TypeInfo: PTypeInfo; begin Result := System.TypeInfo(T); end;
Now, you can obtain the type information for any type by simply using TypeOf<T>.TypeInfo:
type TRecord<T> = record FVal: T; end; TIntRecord = TRecord<Integer>; begin // TypeInfo(TIntRecord); // Fails with compile-time error; WriteLn(GetTypeName(TypeOf<TIntRecord>.TypeInfo)); ReadLn; end.
You can also use this construct to obtain the type information for generic types from within themselves:
type TSomeRec<T> = record function GetMyName: String; end; function TSomeRec<T>.GetMyName(): String; begin // Result := GetTypeName(TypeInfo(TSomeRec<T>)); // Fails Result := TypeOf<TSomeRec<T>>.Name; end;
The only thing to notice is that compile time [DCC Error] E2134 Type ‘XXX’ has no type info errors will not be triggered for types having no type info. Instead, the TypeOf<T>.TypeInfo method will return nil.