Converting a value of type <T> to Variant, is this possible?

here is a snippet showing what I'm trying to achieve:

type TMyObject<T> = class (TObject) function GetVarType(Value: T): TVarType; end; function TMyObject<T>.GetVarType(Value: T): TVarType; var TmpValue: Variant; begin TmpValue := Variant(Value); //Invalid typecast Result := VarType(TmpValue); end; 

I know the above apporach with type is naive, but I hope you get this idea. I would like to replace it with some conversion mechanism.

TMyObject will always have a simple type type Integer, String, Single, Double.

The purpose of such a conversion is that the VarType function gives me an integer constant for every simple type that I can store somewhere else.

I would like to know if such a conversion is possible?

Thank you for your time.

+6
source share
4 answers

You can use RTTI to get this information, just check the value of the TTypeInfo.Kind property:

Check out this sample code.

 {$APPTYPE CONSOLE} uses TypInfo, Variants, Generics.Collections, SysUtils; type TMyObject<T> = class (TObject) function GetVarType(Value: T): TVarType; end; function TMyObject<T>.GetVarType(Value: T): TVarType; begin Case PTypeInfo(TypeInfo(T))^.Kind of tkInteger : Result:=varInteger; tkFloat : Result:=varDouble; tkString : Result:=varString; tkUString : Result:=varUString; //add more types here End; end; Var LObj : TMyObject<Integer>; begin try Writeln(VarTypeAsText(TMyObject<Integer>.Create.GetVarType(5))); Writeln(VarTypeAsText(TMyObject<String>.Create.GetVarType('Test'))); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. 

it will return

 Integer UnicodeString 
+6
source

This is trivially resolvable in Delphis with extended RTTI (2010 and newer). It is a pity that you are limited to 2009: (

 function TMyObject<T>.GetVarType(Value: T): TVarType; begin Result := VarType(TValue.From<T>(Value).AsVariant); end; 

This only works for simple types, but this restriction was asked in the question.

+7
source

I do not see how this can be done with generics. The compiler needs to know that an instance of type T can be assigned to Variant for any possible T It is not possible to indicate that this is possible.

If these were templates, as in C ++, then that would be trivial.

+1
source

Thanks guys for your answers:

As shown in @RRUZ, this is possible (I do not mean strict assignment, but extraction of the data type). I worked on my own, waiting for an answer and found a more general solution.

Therefore, I suggest it here:

 type TMyObject<T> = class (TObject) function GetVarType(Value: T): TVarType; end; function TMyObject<T>.GetVarType(Value: T): TVarType; begin Result := GetTypeData(TypeInfo(T)).varType; end; 

Thanks again!

+1
source

Source: https://habr.com/ru/post/900057/


All Articles