将类型的值<T>转换为变体,可以吗?



下面是一个片段,显示了我想要实现的目标:

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;

我知道上面使用类型转换的方法很幼稚,但是我希望你能理解。我想用某种转换机制来代替它。

TMyObject将始终是简单类型,如Integer, String, Single, Double。

这种转换的目的是函数VarType为每个简单类型提供整型常量,我可以将其存储在其他地方。

我想知道这种转换是否可能?

感谢您的宝贵时间。

在delphi中使用增强的RTTI(2010及更新版本)很容易解决。可惜你仅限于2009年:

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

这只适用于简单类型,但这是问题中指定的约束。

您可以使用RTTI来获取此信息,只需检查TTypeInfo.Kind属性的值:

检查这个示例代码

{$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.

这将返回

Integer
UnicodeString

我不明白用泛型怎么可能做到这一点。编译器需要知道类型T的实例可以分配给任何可能的TVariant。你没有办法告诉编译器这是可能的。

如果这是c++中的模板,那么它将是微不足道的。

谢谢大家的回答:

正如@RRUZ所展示的那样,这是可能的(我的意思不是严格的分配,而是提取数据的类型)。我一直在自己工作,等待任何答案,并找到了一个更通用的解决方案。

所以我把它放在这里:

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;

再次感谢!

相关内容

  • 没有找到相关文章

最新更新