Einzelnen Beitrag anzeigen

Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#12

Re: [Variants] 0 = Unassigned, wieso das denn?

  Alt 8. Jul 2008, 22:01
Zitat von alzaimar:
Ich bin davon ausgegangen, das ein Variant 'unassigned', 'Null' oder einen echten Wert haben kann.
Hierbei ist ganz speziell beim Variant zu beachten, dass man außer dem Wert auch verschiedene Datentypen zuweisen kann, was eine Vergleich erschwert!

Zitat von alzaimar:
Wenn 'Unassigned' einen nicht zugewiesenen Variant bezeichnet, ...
Hier liegt evtl. der Denkfehler. Sieh dir doch mal die Deklaration an. "Unassigned" bezeichnet nicht, sondern weist zu.

Entschuldige bitte folgenden flapsigen Vergleich, aber ich hoffe, er hilft.

Delphi-Quellcode:
if Äpfel1 = Äpfel2 then ... // gültiger Vergleich
if Äpfel1 = Essenfassen then ... // "ungüliger" Vergleich
Hinzu kommt, dass in Delphi boolsche Bedingungen mit 0 für false und alles andere für true gehandhabt wird. Das heißt, wenn deine if-Abfrage etwas anderes als 0 ergibt, wird es als true interpretiert.

Und mal ehrlich, wenn man das mal so betrachtet:

Delphi-Quellcode:
if v = unassigned then
if "Variable mit irgendeinem Typ und irgendeinem Wert" = "Leere Variable, die irgendeinen Typ und irgendeinen Werte annehmen kann" then
Ich weiß, diese Vergleiche hinken! Aber bitte sieh es so, dass ich versuche, Licht in diese Zusammenhänge zu bringen. (Ich will nix Böses! )

Zitat:
Nein, nicht leer, sondern 'nicht zugewiesen'. Laut Variant-Definition gibt es da einen Unterschied.
Da hattu recht!

Zitat:
In SQL initialisiere ich einen Wert mit NULL, bei Variants mit UnAssigned, denn NULL ist etwas anderes. Also, ich prüfe einmal auf 'jemals etwas zugewiesen'
Das sehe ich genauso. Zusätzlich kann man mit Unassigned eine Variant auch wieder jungfräulich machen. Als wäre nie was gewesen. Würde das nur in anderen Bereichen funktionieren!


Zitat:
Eigentlich habe ich diesen Code;
Delphi-Quellcode:
If MyVariant = Null Then
  Writeln('Die Variante ist NULL')
Else if MyVariant = Unassigned Then
  Writeln('Der Variante wurde nie etwas zugewiesen')
else
  Writeln('Die Variante hat einen nicht leeren Inhalt');
Was ich erwarten würde:
"Unassigned = X", wenn X=Unassigned und "Unassigned <> X" für alle anderen X. Das trifft aber nicht zu.
Äh, ... häh?

Nach der von Dir zitierten OH (wo ich ruhig mal hätte nachschauen können), scheint ein Vergleich mit UnAssigned nicht zulässig. Das ist aber BS, denn wenn ich etwas zuweisen und ausgeben kann, muss ich auch darauf prüfen können. Was ist BS?

Sehen wir uns doch mal eine Variant-Variable an. Was ist das?

Die MSDN schreibt da seitenweise Definitionen und wasweißichwasnoch dazu.

Nur ein kurzer Ausschnitt:

Eine Variante kann zur Laufzeit die verschiedensten Typen annehmen. Records, Mengen, statische Arrays, Dateien, Klassen, Klassenreferenzen und Zeiger sind jedoch standardmäßig nicht erlaubt. Varianten können also Werte beliebigen Typs mit Ausnahme von strukturierten Typen und Zeigern enthalten. Wenn Varianten Interfaces enthalten, kann über diese auf ihre Methoden und Eigenschaften zugegriffen werden. (Weitere Informationen finden Sie unter Objekt-Interfaces .) Varianten können auch dynamische Arrays und variante Arrays (ein spezieller Typ von statischen Arrays) aufnehmen (siehe "Variante Arrays"). Varianten können in Ausdrücken und Zuweisungen mit anderen Varianten, aber auch mit Integer-Werten, reellen Werten, Strings und Booleschen Werten kombiniert werden.

Lassen wir das mal bei Seite. Ich versuche mich mal mit einer eigenen "gutbürgerlichen" Definition:
Eine Variant Varibale kann viele verschiedene Werte und Datentypen annehmen.

Wie will man nun zwei Variants mit einander vergleichen? Läuft ein solcher Vergleich nicht darauf hinaus, dass "Die Variable auf der linkgen Seite, die alle möglichen Datentypen und Werte annehmen kann" gleich "Der Variable auf der rechten Seite ist, die ebenfalls alle möglichen Datentypen und werte annehmen kann"?

Das ist der alte "Äpfel mit Birnen vergleichen"-Vergleich.

Probier mal das, vielleicht bringt das Licht in das Verständnis:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  p1: Pointer; // <- kein Variant, sondern Pointer !
  p2: Pointer; // <- kein Variant, sondern Pointer !
  s: string;
begin

  // p1 und p2 sind uninitialisiert
  if p1 = p2 then
    ShowMessage('sind gleich')
  else
    ShowMessage('sind gleich');

  p1 := nil; // auch wenn man diese Zeile weglässt, Ergebnis bleibt gleich

  if p1 = p2 then
    ShowMessage('sind gleich')
  else
    ShowMessage('sind gleich');

  p2 := @s; // auch das hier kann man weglassen oder hinschreiben, der
             // nachfolgende Vergleich bringt immer das gleiche Ergebniss

  if p1 = p2 then
    ShowMessage('sind gleich')
  else
    ShowMessage('sind gleich');
end;
Es gibt einfach Dinge, die kann man nicht miteinander vergleichen!

Guido.

Edit: Leicht formatiert.
Edit2: Doch noch heftig formatiert.
  Mit Zitat antworten Zitat