Frage NULL-Werte in Varianten mit Delphi verwalten


Ich arbeite mit einer COM-Komponente, die viel ausmacht Variant Eigenschaften, aber manchmal sind diese Werte null. Wenn ich versuche, diese Werte in eine Zeichenfolge (oder einen anderen Delphi-Typ) zu konvertieren, löst die Anwendung eine Ausnahme wie diese aus:

Die Variante des Typs (Null) konnte nicht in Typ (String) konvertiert werden

Wenn ich jedoch .net verwende, um dieselben Eigenschaften aufzurufen, und die Werte null sind, werden keine Ausnahmen ausgelöst und die Nullwerte werden als leere Zeichenfolgen behandelt.

Meine Frage gibt es eine Möglichkeit, diese Null-Werte von Delphi mit diesen Ausnahmen umzugehen?

Danke im Voraus.


16
2018-05-09 18:33


Ursprung


Antworten:


Versuchen Sie die Einstellung NullStrictConvert zu Falsch.

Da es sich um eine globale Variable handelt, benutze ich sie wie folgt, um Nebenwirkungen zu minimieren:

var
  OldNullStrictConvert: Boolean;
begin
  OldNullStrictConvert := NullStrictConvert;
  NullStrictConvert := False;
  try
    // code containing conversions
  finally
    NullStrictConvert := OldNullStrictConvert;
  end;
end;

(In Wirklichkeit habe ich eine Guardian-Schnittstelle daraus gemacht.)

NB: Wo es machbar ist, bevorzuge ich Code wie Labyrinthist es.


27
2018-05-09 18:34



Die angenommene Antwort ändert eine globale Einstellung und kann unbeabsichtigte Nebeneffekte auf den Betrieb von anderem Code haben, der funktionierte, bevor Sie ihn änderten.

Zuerst könntest du es einfach benutzen VarToStrDefZweitens, wenn Sie eine andere Funktionalität als das zur Verfügung stellen müssen, dann würde ich meinen Code meine eigene Funktion MyVarToStr nennen, und es so machen:

resourcestring
    SNilValue = '[nil]';


function VarIsAssigned(v:Variant):Boolean; inline;
begin
          result := (v<>Variants.Null) and (not VarIsNull(V));
end;


function MyVarToStr( v:Variant):String;
begin
  if VarIsAssigned(v) then
    result := VarToStr(v)
else
    result := SNilValue;
end;

Da es scheint, dass VarToStrDef genug sein sollte, möchte ich nur zeigen, dass es besser ist, Ihren Code zu schreiben und Ihren eigenen Code aufzurufen, als zu versuchen, das Standardverhalten von VCL / RTL-Bibliothekscode "global zu ändern".


18
2018-05-09 23:04



Dies ist ein dokumentiertes Verhalten von VarToStr Funktion. Es besteht keine Notwendigkeit, ein Rad neu zu erfinden.

Null-Variante ist distinct Typ (ja, es ist ein Typ, nicht nur ein Wert), der entweder fehlt oder bezeichnet unbekannte Daten. Damit, streng sprechende, regelmäßige Variante dynamische Eingabe sollte nicht mit passieren Null Werte (illustriert und in RTL-Standardeinstellungen reflektiert).

gegeben:

var
  V: Variant;
  S: string;

besserer Code

S := VarToStr(V);             { stongly-typed explicit conversion }

relativ guter Code

if not VarIsNull(V) then      { program knows what it does, but reproduces RTL behaviour }
  S := V
else
  S := NullAsStringValue;

schlechter Code

NullStrictConvert := False;   { smelly, from now on Null variant loses its specifics }
S := V;

noch schlimmer Code

try
  S := V;
except on Eaten: Exception do { stinky PHP-style, hiding error instead of fixing it }
  S := NullAsStringValue;
end;

HINWEIS: Die meisten späten Delphi.NET zeigt genau das gleiche Verhalten auf Null-Varianten, so dass OP Bemerkung zu .NET ist fraglich.


12
2018-05-10 02:49



..von user422039 Code VarToStr verwenden sonst S: = V-Relays bei einer impliziten Konvertierung, die zu unterschiedlichen Ergebnissen in verschiedenen Umgebungen führen kann:

S := VarToStr(V);
or
S := VarToStrDef(V, yourdefaultvalue);

4
2018-02-09 07:55



VarToStr() und VarToStrDef() sind der richtige und richtige Weg, um eine Null zu konvertieren Variant zu einem String, wenn sie explizit intern nach Nullwerten suchen.


4
2018-05-08 01:48