![]() |
Warum gibt es hier einen VarCastError?
Ich habe die folgende Funktion:
Delphi-Quellcode:
Die hat bei einen Kunden einen VarCastError (@VarToInteger) ausgelößt. Wo genau und warum wurde nicht übermittelt und ich weiß auch nicht welcher Kunde.
function VarToIntDef(const V: Variant; const ADefault: Integer): Integer;
begin if VarIsOrdinal(V) and not VarIsEmptyOrNull(V) then Result := V else Result := ADefault; end; Wo liegt der Fehler? Auf was müsste ich V setzen um den VarCastError auszulösen? |
AW: Warum gibt es hier einen VarCastError?
Wenn es Ordinal (varSmallInt, varInteger, varBoolean, varShortInt, varByte, varWord, varUInt32, varInt64 oder varUInt64) ist, dann kann es niemals Empty oder Null (varEmpty oder varNull) sein.
Nunja, ein UInt32, Int64 oder UInt64 darin wird in den Integer (Int32) nicht rein passen.
Delphi-Quellcode:
Ergibt zwar keinen VarCastError, aber zumindestens ein ERangeError (Fehler bei Bereichsprüfung) kommt raus.
var
V: Variant; i: Integer; begin V := Int64(1234567890123); if VarIsOrdinal(V) then i := V else i := 123; if i = 0 then ; end; Warum schaust du also nicht selbst etwas in die Funkionen rein und guckst, wo/wann ein CastError geworfen wird? System.Variants._VarToInteger liefert einen CastError bei Null oder bei einem unpassendem String, aber nichts davon kommt am VarIsOrdinal vorbei. Fazit: Dein VarIsEmptyOrNull ist dran Schuld, auch wenn niemand weiß was das macht, weil jemand vergaß es zu sagen. |
AW: Warum gibt es hier einen VarCastError?
Zitat:
Delphi-Quellcode:
Da wird doch nichts nach Int gewandelt? Wie kann die also Schuld daran sein? Oder übersehe ich was? Nur so aus Interesse, denn Du hast natürlich recht: Die Funktion brauche ich gar nicht mehr...
function VarIsEmptyOrNull(const Value: Variant): Boolean;
begin Result := VarIsClear(Value) or VarIsEmpty(Value) or VarIsNull(Value) or (VarCompareValue(Value, Unassigned) = vrEqual); if not Result and VarIsStr(Value) then Result := Value = ''; end; |
AW: Warum gibt es hier einen VarCastError?
Sagen wir es mal so: Ich fand in den anderen Funktionen (noch) nichts, was für diesen Fehler verantwortlich sein könnte, also blieb erstmal nur noch das übrig. :angle2:
PS: Unassigned = Clear und Empty ist auch im Clear mit enthalten Entsprechend bleibt funktionell kaum noch etwas übrig.
Delphi-Quellcode:
VarIsEmptyOrNull hat auf's Ergebnis keinen Einfluss,
function VarToIntDef(const V: Variant; const ADefault: Integer): Integer;
begin if VarIsOrdinal(V) {and not VarIsEmptyOrNull(V)} then // ist es Ordinal, ist es gleichzeitig niemals das Andere Result := V //:= _VarToInteger(V) // größer signed 32-Bit knallt es else Result := ADefault; end; {function VarIsEmptyOrNull(const Value: Variant): Boolean; begin Result := VarIsClear(Value) or VarIsNull(Value); if not Result and VarIsStr(Value) then Result := Value = ''; end;} aber es wird dennoch ausgeführt, wenn VarIsOrdinal zutrifft, wobei es dann immer False lieft. (und
Delphi-Quellcode:
, bzw.
and not False
Delphi-Quellcode:
ändert dann nichts mehr)
and True
VarCompareValue und VarIsEmpty werden immer nur sinnlos ausgeführt. Sie liefern immer nur True, wenn das VarIsClear bereits gemacht hatte und dann werden sie vom OR nicht mehr ausgeführt. Alles in VarIsEmptyOrNull wird auch nur ausgefüjrt, wenn VarIsOrdinal True sagte, wo dann alles im VarIsEmptyOrNull nur noch False liefern kann. (es wird also alles zwar ausgeführt, aber sinnlos, da es das Endergebnis nicht beeinflussen kann, weil es ja immer
Delphi-Quellcode:
sein wird, sobald es ausgeführt wird)
and True
Was am Ende übrig bleibt, kann eigentlich keinen CastError auslösen (abgesehn von eventuell dem, was sinnlos enthalten war) und übrig bleibt noch ein Fehler, wenn es größer als 32 Bit wird. (ERangeError) Du hast also viel Code, der eigentlich nichts macht, da er keine Auswirkung auf's Ergebnis hat, außer eventuell Fehler zu verursachen. Lösung:
Delphi-Quellcode:
Allerdings fehlt bei deinem Code, z.B. die Behandlung von nummerischen Strings, welche ich oben noch heimlich mit eingefügt hab.
function VarToIntDef(const V: Variant; const ADefault: Integer): Integer;
begin if VarIsType(V, [varSmallInt, varInteger, varBoolean, varShortInt, varByte, varWord]) then // entspricht VarIsOrdinal bis Int32 (signed 32-Bit) Result := V {else if VarIsStr(V) then Result := StrToIntDef(V, ADefault)} else Result := ADefault; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:05 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz