Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Cast von Nullable<> (Spring4D) nach Variant (https://www.delphipraxis.net/181812-cast-von-nullable-spring4d-nach-variant.html)

Der schöne Günther 10. Sep 2014 13:14

Cast von Nullable<> (Spring4D) nach Variant
 
Ich habe mich vor den Delphi-Variants immer gedrückt und weiß wenig darüber. Hier, was ich glaube:

Delphi-Quellcode:
System.Variants.Null()
liefert ein Variant, das bei seinen Casts immer "Null" zurückgibt. Auf eine Zahl ist es
Delphi-Quellcode:
0
, auf einen String ist es ein leerer String, auf eine Referenz ist es
Delphi-Quellcode:
Nil
usw.

Dementgegen steht
Delphi-Quellcode:
System.Variants.Unassigned()
: Das liefert einen Variant, der nichts ist. Man kann ihn nirgendwo hin casten, es steckt nichts drin.

Richtig soweit? Wenn ja wundert es mich, warum ein leeresSpring4D-Nullable<> (also mit nichts drin) beim Cast auf ein Variant
Delphi-Quellcode:
Null()
zurückgibt und nicht
Delphi-Quellcode:
Unassigned()
.

Welchen Grund hat das? Hier noch einmal der aktuelle Sourcecode in Spring:
Delphi-Quellcode:
class operator Nullable<T>.Implicit(const value: Nullable<T>): Variant;
var
  v: TValue;
begin
  if value.HasValue then
  begin
    v := TValue.From<T>(value.Value);
    if v.IsType<Boolean> then
      Result := v.AsBoolean
    else
      Result := v.AsVariant;
  end
  else
    Result := Null; // Warum?
end;

Dejan Vu 10. Sep 2014 13:25

AW: Cast von Nullable<> (Spring4D) nach Variant
 
'Null' ist einfacher zu handhaben als 'Unassigned'. Aber wissen tut das nur Meister Stevie.

Nersgatt 10. Sep 2014 14:10

AW: Cast von Nullable<> (Spring4D) nach Variant
 
wenn du einen Variant mit dem Wert Null einem Integer oder einer Stringvariable zuweist, bekommst Du doch nicht 0, bzw. '' sondern eine Exception.
Für mich als Datenbankentwickler ist Null halt "leer". Unassigned kommt in meinen Gedankengängen nicht vor :stupid:

Somit kann ich mit der Behandlung, wie es in Spring4D gelöst ist, sehr sehr gut leben. Ich hab (nach dem Vortrag von Stevie am Samstag) meine Anwendung von der Verwendung von Variants auf TNullable umgestellt. Das hat problemlos funktioniert und macht den Code deutlich schöner.

Stevie 10. Sep 2014 15:39

AW: Cast von Nullable<> (Spring4D) nach Variant
 
Soweit ich weiß, ist Unassigned eher für OLE Zeugs - siehe auch Dokumentation, die da sagt:
Zitat:

Note: Unassigned is useful with variants referencing OLE Automation Objects that you want to keep "alive" until another value is assigned to the variant.
Und da der Typ Nullable<T> und nicht Unassignable<T> heißt, machts imho eher Sinn, Null zurückzuliefern, wenn der Nullable<T> leer ist.

Beim Hineingeben eines Variants sorgen sowohl Null als auch Unassigned (es wird mit VarIsNull or VarIsEmpty geprüft) dafür, dass es ein leerer Nullable<T> ist.
Allerdings muss sich beim herausgeben eines Variants für eins von beidem entschieden werden und da macht Null wie zuvor erwähnt eher Sinn.

Zitat:

Zitat von Der schöne Günther (Beitrag 1272012)
Delphi-Quellcode:
System.Variants.Null()
liefert ein Variant, das bei seinen Casts immer "Null" zurückgibt. Auf eine Zahl ist es
Delphi-Quellcode:
0
, auf einen String ist es ein leerer String, auf eine Referenz ist es
Delphi-Quellcode:
Nil
usw.

Dementgegen steht
Delphi-Quellcode:
System.Variants.Unassigned()
: Das liefert einen Variant, der nichts ist. Man kann ihn nirgendwo hin casten, es steckt nichts drin.

Genau das Gegenteil ist der Fall, eine Zuweisung von Unassigned auf einen anderen Typ gibt immer den default Wert dieses Typs zurück (0, Leerstring, etc).
Bei Null gibts einen EVariantTypeCastError.

Zitat:

Zitat von Nersgatt (Beitrag 1272026)
Ich hab meine Anwendung von der Verwendung von Variants auf TNullable umgestellt. Das hat problemlos funktioniert und macht den Code deutlich schöner.

Das freut mich, dass es so gut geklappt hat.

Dejan Vu 10. Sep 2014 15:46

AW: Cast von Nullable<> (Spring4D) nach Variant
 
Soweit ich mich erinnere, kann auf 'v = Null' geprüft werden ('v' ist ein Variant), aber auf 'v = Unassigned' nicht. Es ist also ein netter Nebeneffekt auch in Hinblick auf den Vergleich, das hier 'Null' geliefert wird.

Stevie 10. Sep 2014 15:48

AW: Cast von Nullable<> (Spring4D) nach Variant
 
Zitat:

Zitat von Dejan Vu (Beitrag 1272048)
Soweit ich mich erinnere, kann auf 'v = Null' geprüft werden ('v' ist ein Variant), aber auf 'v = Unassigned' nicht. Es ist also ein netter Nebeneffekt auch in Hinblick auf den Vergleich, das hier 'Null' geliefert wird.

Doch geht beides, mit dem kleinen Haken, dass
Delphi-Quellcode:
0 = Unassigned
true ist und sich Unassigned somit nicht als expliziter Zustand für "ist leer" benutzen lässt.

Der schöne Günther 10. Sep 2014 16:16

AW: Cast von Nullable<> (Spring4D) nach Variant
 
Zitat:

Zitat von Stevie (Beitrag 1272046)
Genau das Gegenteil ist der Fall, eine Zuweisung von Unassigned auf einen anderen Typ gibt immer den default Wert dieses Typs zurück (0, Leerstring, etc).
Bei Null gibts einen EVariantTypeCastError.

Oh, stimmt, da habe ich mich vertan.

Mein Szenario war folgendes: Ich habe ein paar Variablen vom Typ
Delphi-Quellcode:
Nullable<IrgendeinTyp>
und muss die in einer TQuery in die Parameter (
Delphi-Quellcode:
Data.DB.TParam
) stecken. Ein
Delphi-Quellcode:
TParam
hat eine Property
Delphi-Quellcode:
Value
vom Typ
Delphi-Quellcode:
Variant
. Der Setter dieser Property setzt die TParam-Eigenschaft
Delphi-Quellcode:
Bound := VarIsClear(variantDings)
. Bound gibt an, ob der Parameter gesetzt ist.

Ja, er ist gesetzt, und zwar auf NULL. Ich habe also, trotz anfänglicher Verwirrung, genau was ich will :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz