转换类型的值变成变体,有可能吗?

发布于 2024-12-12 00:51:28 字数 527 浏览 0 评论 0原文

这是一个显示我想要实现的目标的片段:

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 为每个简单类型提供整数常量,我可以将其存储在其他地方。

我想知道这样的转换是否可行?

感谢您抽出时间。

here is a snippet showing what I am 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 that above apporach with typecast is naive but I hope you get the idea. I would like to replace it with some conversion mechanism.

TMyObject will be always of simple type like Integer, String, Single, Double.

The purpose of such conversion is that function VarType gives me integer constant for each simple type which I can store somewhere else.

I would like to know if such conversion is possible?

Thanks for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

零度℉ 2024-12-19 00:51:28

它可以在具有增强 RTTI(2010 及更新版本)的 Delphis 中轻松解决。太糟糕了,您仅限于 2009 年:(

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

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

It's trivially solvable in Delphis with enhanced RTTI (2010 and newer). Too bad you're limited to 2009 :(

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

This works only for simple types but that was a constraint specified in the question.

白云不回头 2024-12-19 00:51:28

您可以使用 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

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

Check 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.

this will return

Integer
UnicodeString
情栀口红 2024-12-19 00:51:28

我不明白如何使用泛型来做到这一点。编译器需要知道类型 T 的实例可以分配给任何可能的 TVariant。您无法告诉编译器这是可能的。

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

I can't see how it could be possible to do this with generics. The compiler needs to know that an instance of type T can be assigned to a Variant for any possible T. There's no way for you to tell that compiler that is possible.

If this were templates as in C++ then it would be trivial.

原野 2024-12-19 00:51:28

感谢大家的回答:

正如 @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;

再次感谢!

Thanks guys for your answers:

As @RRUZ have shown it is possible (I mean not strict assigment but extracting the type of data). I was working on my own while waiting for any answer and have found a more generic solution.

So I am positing 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;

Once again thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文