Строковое представление типа содержимого Variant? - PullRequest
6 голосов
/ 24 мая 2009

Во-первых, извиняюсь за мой английский, надеюсь, имеет смысл то, что я здесь написал. Теперь к моей проблеме.

Как получить строковое представление содержимого type Variant, используя TypInfo.GetEnumName (). Я попробовал следующее, без удачи, я получаю числовое представление.

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

Спасибо.

Ответы [ 4 ]

12 голосов
/ 25 мая 2009

Просто используйте встроенную функцию 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;
3 голосов
/ 24 мая 2009

Цитирование из справки Delphi 2007:

Используйте GetEnumName для преобразования перечислимого значения Delphi в символическое имя, которое представляет его в коде.

Это означает, что вы не можете использовать его для этой цели, так как TVarData.VType является не перечисляемым значением, а целым числом, которое установлено в одну из констант в System.pas, которые принимаются из файла Windows SDK wtypes.h . Посмотрите на источник GetEnumName () , он сразу же возвращает строку, содержащую значение целого числа.

Edit:

есть ли другой способ получить строковое представление 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;
1 голос
/ 24 мая 2009

Поскольку это не enum, вам придется делать это вручную. Напишите что-то вроде этого:

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

Или, поскольку значения в System.pas перечислены по порядку, вы можете попробовать объявить константный массив строк, и ваша функция VariantTypeName вернет соответствующий элемент массива.

0 голосов
/ 18 января 2010

Вот мысль для версий Delphi, которые не поддерживают VarTypeAsText: Вы можете определить тип перечисления самостоятельно, следуя значениям VType:

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

(Заполните также неиспользуемые слоты перечисления - см. Почему я получаю сообщение об ошибке «тип не имеет типовой информации» с типом перечисления для объяснения этого).

Далее, используйте эти функции для чтения типа Вариантов как своего собственного типа перечисления:

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