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.