Строковое представление типа содержимого варианта?

StackOverflow https://stackoverflow.com/questions/903791

Вопрос

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

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

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

Спасибо.

Это было полезно?

Решение

Просто используйте встроенную функцию 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;

Другие советы

Цитирую из справки Delphi 2007:

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

Это означает, что вы не можете использовать его для этой цели, поскольку ТВарДата.Тип является не перечисляемым значением, а целым числом, для которого установлена одна из констант в 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;

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

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

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

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

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

(Заполните также неиспользуемые ячейки перечисления - см. Почему я получаю ошибку "тип не имеет typeinfo" с типом enum для обоснования этого).

Затем используйте эти функции, чтобы прочитать тип вариантов как ваш собственный тип перечисления :

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;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top