Строковое представление типа содержимого варианта?
-
05-09-2019 - |
Вопрос
Во-первых, прошу прощения за мой английский, я надеюсь, что в том, что я здесь написал, есть смысл.Теперь к моей проблеме.
Как я могу получить строковое представление содержимого Тип варианта, использующего 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;