Variant 内容类型的字符串表示形式?

发布于 2024-07-21 07:13:53 字数 254 浏览 5 评论 0原文

首先,对我的英语表示歉意,我希望我在这里写的内容有意义。 现在我的问题。

如何使用 TypInfo.GetEnumName() 获取变体内容类型的字符串表示形式。 我尝试了以下操作,但没有运气,我得到了数字表示。

myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );

谢谢。

First, apologies for my English, I hope it makes sense what I`ve written here. Now to my problem.

How can I get the string representation of the content type of a Variant using TypInfo.GetEnumName(). I have tried the following, without luck, I get a numeric representation.

myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );

Thank you.

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

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

发布评论

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

评论(4

甜味超标? 2024-07-28 07:13:53

只需使用内置的 Delphi 函数即可获取 Variant 类型的字符串表示形式。

var
  MyVariantType: string;
  MyVariant: Variant;
begin
  MyVariant := 'Hello World';
  MyVariantType := VarTypeAsText(VarType(MyVariant));
  ShowMessage(MyVariantType); //displays: String

  MyVariant := 2;
  MyVariantType := VarTypeAsText(VarType(MyVariant));
  ShowMessage(MyVariantType); //displays: Byte
end;

Just use the build-in Delphi function for getting the string representation of a Variant type.

var
  MyVariantType: string;
  MyVariant: Variant;
begin
  MyVariant := 'Hello World';
  MyVariantType := VarTypeAsText(VarType(MyVariant));
  ShowMessage(MyVariantType); //displays: String

  MyVariant := 2;
  MyVariantType := VarTypeAsText(VarType(MyVariant));
  ShowMessage(MyVariantType); //displays: Byte
end;
痴梦一场 2024-07-28 07:13:53

引用Delphi 2007帮助:

使用 GetEnumName 将 Delphi 枚举值转换为在代码中表示它的符号名称。

这意味着您不能将它用于此目的,因为 TVarData.VType 不是枚举值,而是一个整数,它被设置为 System.pas 中的常量之一,这些常量取自Windows SDK wtypes.h 文件。 查看GetEnumName()的源代码,它确实立即返回一个包含整数值的字符串。

编辑:

是否还有其他方法来获取 TVarData.VType 的字符串表示形式

您可以手动确定字符串表示形式。 首先,您需要意识到该整数中编码了几位信息,因此简单的 case 语句或数组查找将不起作用。 低 12 位是类型掩码,高位编码有关它是向量还是数组类型以及是否通过引用给出的信息。 重要的部分是:

const
  varTypeMask = $0FFF;
  varArray    = $2000;
  varByRef    = $4000;

所以你可以这样做:

function VariantTypeName(const AValue: TVarData): string;
begin
  case AValue.VType and varTypeMask of
    vtInteger: Result := 'integer';
    // ...
  end;

  if AValue.VType and varArray <> 0 then
    Result := 'array of ' + Result;
  if AValue.VType and varByRef <> 0 then
    Result := Result + ' by ref';
end;

Quoting from the Delphi 2007 help:

Use GetEnumName to convert a Delphi enumerated value into the symbolic name that represents it in code.

That means that you can't use it for that purpose, as TVarData.VType is not an enumerated value, but an integer which is set to one of the constants in System.pas that are taken from the Windows SDK wtypes.h file. Look at the source of GetEnumName(), it does immediately return a string containing the value of the integer.

Edit:

is there any other way to get the string representation of TVarData.VType

You can determine the string representation manually. First you need to be aware of that there are several bits of information encoded in that integer, so a simple case statement or array lookup will not work. The lower 12 bits are the type mask, and the upper bits encode information about whether it is a vector or array type and whether it is given by reference or not. The important parts are:

const
  varTypeMask = $0FFF;
  varArray    = $2000;
  varByRef    = $4000;

So you could do something like:

function VariantTypeName(const AValue: TVarData): string;
begin
  case AValue.VType and varTypeMask of
    vtInteger: Result := 'integer';
    // ...
  end;

  if AValue.VType and varArray <> 0 then
    Result := 'array of ' + Result;
  if AValue.VType and varByRef <> 0 then
    Result := Result + ' by ref';
end;
走过海棠暮 2024-07-28 07:13:53

由于它不是枚举,因此您必须手动执行此操作。 编写如下内容:

function VariantTypeName(const value: TVarData): string;
begin
  case value.VType of
    vtInteger: result := 'integer';
    //and so on
end;

或者,由于 System.pas 中的值是按顺序列出的,因此您可以尝试声明一个 const 字符串数组,并让您的 VariantTypeName 函数返回该数组的适当成员。

Since it's not an enum, you'll have to do it manually. Write something like this:

function VariantTypeName(const value: TVarData): string;
begin
  case value.VType of
    vtInteger: result := 'integer';
    //and so on
end;

Or, since the values in System.pas are listed in order, you could try declaring a const array of strings and have your VariantTypeName function return the appropriate member of the array.

帅气尐潴 2024-07-28 07:13:53

对于不支持 VarTypeAsText 的 Delphi 版本,这里有一个想法:您可以自己定义一个遵循 VType 值的枚举类型:(

type
  {$TYPEINFO ON}
  TMyVarType = (
    varEmpty = System.varEmpty, 
    varNull = System.varNull,
    // etc...
    );

也填充未使用的枚举槽 - 请参阅 为什么我会收到枚举类型的“type has no typeinfo”错误这背后的推理)。

接下来,使用这些函数将 Variants 类型读取为您自己的枚举类型:

function MyVarType(VType: TVarType): TMyVarType; overload;
begin
  Result := TMyVarType(VType);
end;

function MyVarType(V: Variant): TMyVarType; overload;
begin
  Result := TMyVarType(TVarData(V).VType);
end;

然后您可以将其转换为如下字符串:

function VarTypeToString(aValue: TMyVarType): string;
begin
  Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;

Here's a thought for Delphi versions that don't support VarTypeAsText: You could define a enumerate type yourself that follows the VType values:

type
  {$TYPEINFO ON}
  TMyVarType = (
    varEmpty = System.varEmpty, 
    varNull = System.varNull,
    // etc...
    );

(Fill the unused enum slots too - see Why do I get "type has no typeinfo" error with an enum type for the reasoning behind this).

Next, use these functions to read the Variants' type as your own enumerate type :

function MyVarType(VType: TVarType): TMyVarType; overload;
begin
  Result := TMyVarType(VType);
end;

function MyVarType(V: Variant): TMyVarType; overload;
begin
  Result := TMyVarType(TVarData(V).VType);
end;

And then you can convert it to a string like this :

function VarTypeToString(aValue: TMyVarType): string;
begin
  Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文