representação em cadeia do tipo de conteúdo de um Variant?
-
05-09-2019 - |
Pergunta
Em primeiro lugar, desculpas para o meu Inglês, eu espero que isso faz sentido que I`ve escrito aqui. Agora para o meu problema.
Como posso obter a representação de string do conteúdo tipo de um Variant usando TypInfo.GetEnumName (). Eu tentei o seguinte, sem sorte, eu recebo uma representação numérica.
myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );
Obrigado.
Solução
Basta usar o build-in função de Delphi para obter a representação de cadeia de um tipo 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;
Outras dicas
Citando a ajuda Delphi 2007:
Use GetEnumName para converter um valor enumerado Delphi para o nome simbólico que representa-lo no código.
Isso significa que você não pode usá-lo para essa finalidade, como TVarData.VType não é um valor enumerado, mas um número inteiro que é definido para uma das constantes em system.pas que são tirada do Windows SDK wtypes.h arquivo. Olhada na fonte de GetEnumName () , ele não retornou imediatamente uma string contendo o valor do inteiro.
Editar:
Existe alguma outra maneira de obter a representação de cadeia de TVarData.VType
Você pode determinar a representação de cadeia manualmente. Primeiro você precisa estar ciente de que existem vários bits de informação codificada em que inteiro, assim que uma simples declaração caso ou matriz de pesquisa não vai funcionar. Os 12 bits mais baixos são o tipo de máscara, e a informação bits de codificação superior sobre se se trata de um tipo de vector ou matriz e se ele é dado por referência ou não. As partes importantes são:
const
varTypeMask = $0FFF;
varArray = $2000;
varByRef = $4000;
Então, você poderia fazer algo como:
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;
Uma vez que não é uma enumeração, você terá que fazê-lo manualmente. Escrever algo como isto:
function VariantTypeName(const value: TVarData): string;
begin
case value.VType of
vtInteger: result := 'integer';
//and so on
end;
Ou, já que os valores em system.pas estão listados em ordem, você pode tentar declarar uma matriz const de cordas e ter a sua função VariantTypeName devolver o membro apropriado da matriz.
Aqui está um pensamento para versões do Delphi que não suportam VarTypeAsText: Você poderia definir um tipo de enumerate-se que segue os valores vtype:
type
{$TYPEINFO ON}
TMyVarType = (
varEmpty = System.varEmpty,
varNull = System.varNull,
// etc...
);
(Preencher os slots não utilizados enum também - veja por que recebo "tipo não tem typeinfo" erro com um tipo enum para o raciocínio por trás disso).
Em seguida, usar essas funções para ler o tipo Variantes, como seu próprio tipo de enumerate:
function MyVarType(VType: TVarType): TMyVarType; overload;
begin
Result := TMyVarType(VType);
end;
function MyVarType(V: Variant): TMyVarType; overload;
begin
Result := TMyVarType(TVarData(V).VType);
end;
E então você pode convertê-lo para uma string como esta:
function VarTypeToString(aValue: TMyVarType): string;
begin
Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;