rappresentazione String del tipo di contenuto di una variante?
-
05-09-2019 - |
Domanda
In primo luogo, le scuse per il mio inglese, spero che senso quello `ve scritto qui. Ora per il mio problema.
Come posso ottenere la rappresentazione di stringa del contenuto Tipo di una variante utilizzando TypInfo.GetEnumName (). Ho provato quanto segue, senza fortuna, ho una rappresentazione numerica.
myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );
Grazie.
Soluzione
utilizzare solo la funzione build-in Delphi per ottenere la rappresentazione di stringa di 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;
Altri suggerimenti
Citando l'aiuto Delphi 2007:
Usa GetEnumName per convertire un valore di Delphi enumerato nel nome simbolico che rappresenta nel codice.
Ciò significa che non è possibile utilizzare per questo scopo, come TVarData.VType non è un valore enumerato, ma un intero che è impostato su una delle costanti in System.pas che sono tratto da Windows SDK wtypes.h file. Guardare la fonte di GetEnumName () , esso ritorna immediatamente una stringa contenente il valore del numero intero.
Modifica
c'è qualche altro modo per ottenere la rappresentazione di stringa di TVarData.VType
È possibile determinare la rappresentazione di stringa manualmente. Per prima cosa è necessario essere consapevoli di che ci sono diversi pezzi di informazioni codificate in quel intero, quindi un semplice caso dichiarazione o matrice di ricerca non funzionerà. I 12 bit inferiori sono il tipo di maschera, ed i bit superiori codificare informazioni se si tratta di un tipo di vettore o matrice e se è dato dal riferimento oppure no. Le parti importanti sono:
const
varTypeMask = $0FFF;
varArray = $2000;
varByRef = $4000;
Così si potrebbe fare qualcosa di simile:
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;
Dato che non è un enum, dovrete farlo manualmente. Scrivere qualcosa di simile:
function VariantTypeName(const value: TVarData): string;
begin
case value.VType of
vtInteger: result := 'integer';
//and so on
end;
In alternativa, dal momento che i valori in System.pas sono elencati in ordine, si potrebbe provare a dichiarare una matrice const di stringhe e hanno la funzione VariantTypeName restituire il membro appropriata della matrice.
Ecco un pensiero per le versioni di Delphi che non supportano VarTypeAsText: Si potrebbe definire il tipo di enumerare te stesso che segue i valori VType:
type
{$TYPEINFO ON}
TMyVarType = (
varEmpty = System.varEmpty,
varNull = System.varNull,
// etc...
);
(Riempire gli slot inutilizzati enum troppo - vedi Perché ricevo "tipo ha nessun errore typeinfo" con un tipo enum per il ragionamento alla base di questo).
Quindi, utilizzare queste funzioni per leggere il tipo di varianti come il tuo tipo di enumerare:
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 poi è possibile convertire in una stringa come questa:
function VarTypeToString(aValue: TMyVarType): string;
begin
Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;