representación de cadena del tipo de contenido de una variante?
-
05-09-2019 - |
Pregunta
En primer lugar, disculpas por mi Inglés, espero que tiene sentido lo que `he escrito aquí. Ahora a mi problema.
¿Cómo puedo obtener la representación de cadena del contenido Tipo de una variante utilizando TypInfo.GetEnumName (). He intentado lo siguiente, sin suerte, consigo una representación numérica.
myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );
Gracias.
Solución
Sólo tiene que utilizar la función de acumulación de Delphi para conseguir la representación de cadena de un 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;
Otros consejos
Citando la ayuda de Delphi 2007:
Uso GetEnumName para convertir un valor de Delphi enumerado en el nombre simbólico que lo representa en el código.
Esto significa que no se puede utilizar para tal fin, como TVarData.VType no es un valor enumerado, pero un número entero que se fija a una de las constantes en System.pas que son tomada desde el SDK de Windows wtypes.h archivo. Mira la fuente de GetEnumName () , no respondió de inmediato una cadena que contiene el valor del entero.
Editar
¿hay alguna otra manera de conseguir la representación de cadena de TVarData.VType
Es posible determinar la representación de cadena manualmente. Primero tendrá que ser conscientes de que hay varios bits de información codificada en ese entero, por lo que una simple afirmación de casos o matriz de búsqueda no va a funcionar. Los 12 bits inferiores son la máscara tipo, y los bits superiores codifican la información acerca de si es un vector o matriz de tipo y si se administra por referencia o no. Las partes importantes son:
const
varTypeMask = $0FFF;
varArray = $2000;
varByRef = $4000;
Por lo que podría hacer 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;
Ya que no es una enumeración, que tendrá que hacerlo manualmente. Escribir algo como esto:
function VariantTypeName(const value: TVarData): string;
begin
case value.VType of
vtInteger: result := 'integer';
//and so on
end;
O, ya que los valores en System.pas se enumeran en orden, usted podría tratar de declarar una matriz const de cadenas y que su función VariantTypeName devolver el miembro apropiado de la matriz.
He aquí un pensamiento para las versiones de Delphi que no soportan VarTypeAsText: Se podría definir una enumeración de tipo sí mismo que sigue los valores vTipo:
type
{$TYPEINFO ON}
TMyVarType = (
varEmpty = System.varEmpty,
varNull = System.varNull,
// etc...
);
(llenar los espacios no utilizados de enumeración también - vea ¿por qué aparece 'tipo no tiene ningún error typeinfo' con un tipo de enumeración para el razonamiento detrás de esto).
A continuación, utilizar estas funciones para leer el tipo de variantes como su propio tipo de enumeración:
function MyVarType(VType: TVarType): TMyVarType; overload;
begin
Result := TMyVarType(VType);
end;
function MyVarType(V: Variant): TMyVarType; overload;
begin
Result := TMyVarType(TVarData(V).VType);
end;
Y a continuación, puede convertirla en una cadena como esta:
function VarTypeToString(aValue: TMyVarType): string;
begin
Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;