![]() |
Delphi-Version: 10.3 Rio
Warum sind Klassenoperatoren nicht bissl intelligenter?
Liste der Anhänge anzeigen (Anzahl: 1)
Warum kann der Compiler nicht auch mal etwas Intelligenz zeigen und den impliziten Cast benutzen, anstatt beim
Delphi-Quellcode:
aufzugeben?
if List[0] = 0 then
Andersrum geht
Delphi-Quellcode:
zum Glück auch nicht, obwohl der Compiler dort ja schon weiß, dass der Vergleich einen Integer ordinalen Typen haben möchte.
if 0 = List[0] then
Delphi-Quellcode:
Oder hier einfach mal die Reihenfolge optimaler anpassen?
type
TTestItem = record private FValue: Integer; function GetValue: Integer; procedure SetValue(const Value: Integer); public class operator Implicit(const Value: Integer): TTestItem; inline; class operator Implicit(const Value: TTestItem): Integer; inline; property RInt: Integer read GetValue; property WInt: Integer write SetValue; property RWInt: Integer read GetValue write SetValue; end; TTestList = record private FItems: TArray<TTestItem>; function GetItem(DummyIndex: Integer): TTestItem; procedure SetItem(DummyIndex: Integer; const Value: TTestItem); public property Item[DummyIndex: Integer]: TTestItem read GetItem write SetItem; default; end; procedure TForm1.FormCreate(Sender: TObject); var List: TTestList; begin List[0] := 123; // Implicit:TTestItem > SetValue > SetItem List[0].WInt := 456; // GetItem > SetValue > lost if List[0] <> 456 then lost; List[0].RWInt := 789; // GetItem > SetValue > lost if List[0] <> 789 then lost; //if List[0] = 0 then ; // GetItem > Implicit:Integer > GetValue = [dcc32 Fehler] E2015 Operator ist auf diesen Operandentyp nicht anwendbar if Integer(List[0]) = 0 then ; // GetItem > Explicit > Implicit:Integer > GetValue if List[0].RInt = 0 then ; // GetItem > GetValue if List[0].RWInt = 0 then ; // GetItem > GetValue end;
Delphi-Quellcode:
Klar, jetzt kann man natürlich auch noch alle möglichen Vergleichsoperatoren und alles auch nochmal umgedreht reinmachen, aber schlauer wäre es mit etwas mehr Intelligenz. :freak:
type
TTest2 = record private FValue: Integer; public class operator Add (const LeftValue: TTest2; RightValue: Integer): Integer; class operator Equal(const LeftValue: TTest2; RightValue: Integer): Boolean; class operator Implicit(const Value: Integer): TTest2; class operator Implicit(const Value: TTest2): Integer; end; procedure TForm1.FormCreate(Sender: TObject); var X: TTest2; begin if X = 0 then ; // Equal(Rec,Int) if 0 = X then ; // Implicit:Integer > Implicit:TTest2 > Equal(Rec,Int) ... erst rechts, dann links? Und das mit den Settern läst sich dadurch verhindern, dass der Record keine Setter bekommt. (implizite Casts als Zuweisung funktionieren erstaunlicher Weise) |
AW: strunzdoofe Kassenoperatoren?
<gelöscht>: hat sich erledigt.
|
AW: strunzdoofe Kassenoperatoren?
glaub schon :roll:
|
AW: strunzdoofe Klassenoperatoren?
Tut mir leid, aber ich checke dein Problem gerade nicht.
Der Equal-Klassenoperator funktioniert bei mir ohne Probleme in dieser Konstellation. Egal wie herum man die Operanden schreibt. Wenn du diesen aber nicht definierst, dann ist es natürlich klar, dass hier kein Vergleich möglich ist. Kannst du evtl nochmal kurz erläutern, was dein Problem ist? Was wirklich nicht funktioniert, egal, ob du den Impliziten Operator überlädst, ist, wenn du versuchst, einen Wert des Typs an eine Funktion zu übergeben. Das wäre durchaus mal einen Fix Wert.
Delphi-Quellcode:
procedure Poop(Arg: Integer);
begin //... end; begin Poop(List[0]); // Jeht nüscht end. |
AW: strunzdoofe Klassenoperatoren?
JA, WENN man diesen Operator einbaut.
Aber stell dir mal vor das wäre Intelligent und würde den ImplicitCast benutzen. Und wierum hat einen großen Einfluss auf die Qualität des Vergleichs. (siehe TTest2) In meinem Fall kann dieses Verhalten sogar einen Fehler erzeugen, wenn sich der Record nicht in einen Integer casten lässt. Zitat:
Das hier ist noch ein einfaches Beispiel gewesen, welches ich als Test erstellt hatte. Der originale Record, wo ich es verwenden wollte, würde jetzt bestimmt nochmal locker 100 weitere Operatoren benötigen, wenn ich dafür alle möglichen Konstellation in allen Richtungen reinmachen müsste. Stattdessen bleibt mir wohl eher alles wegzuwerfen und eine weniger schöne Syntax zu verwenden, anstatt die paar Konvertierungen nur in den Record zu packen. |
AW: strunzdoofe Klassenoperatoren?
Ups, ja, das geht tatsächlich.
Aber es funktioniert nicht in jeder Konstellation. Bin ganz früher über das hier selbst gestolpert, als ich die Operatoren ausprobiert habe... ![]() Das funktioniert nämlich nicht... |
AW: strunzdoofe Klassenoperatoren?
Bitte gib Deinem Thema einen aussagekräftigen Titel ...
|
AW: strunzdoofe Klassenoperatoren?
Zitat:
|
AW: strunzdoofe Klassenoperatoren?
Es geht ja noch weiter ... Delphi/Pascal kennt keine Unterscheidung zwischen Bitwise und Logical, bei and/or/xor, aber du kannst beides Deklarieren (für das komische BCPP),
was erstmal nicht schlimm ist, wenn dir der Compiler eine Meldung geben würde, dass er das Andere nicht verwendet. Oder wenn du Equal deklariert hast, dann könnte man das für NotEqual mitverwenden, wenn dieses nicht Deklariert wurde. Oder warum nicht gleich "eine" CompareMethode für Alles? mit den drei Ergebnissen -1, 0 und 1 anstatt 6 Methoden. ![]() Bzw. wenn etwas davon nicht deklariert wurde, dann könnte der Compiler mit 1 bis 2 Aufrufen alles Andere daraus generieren. (z.B. Equal und LessThan reicht aus, um alle Anderen zu emulieren) Bei Add, And, Or und Xor ist die Reihenfolge der Parameter egal, also würde eine Variante reichen und der Compiler dreht die anderen Möglichkeiten einfach um. Ich hatte mir auch ein
Delphi-Quellcode:
deklariert, aber ist bei der Aufrufstelle was blöde.
class operator In(const LeftValue: TTestItem; const RightValue: array of Integer): Integer;
Delphi-Quellcode:
// meldet mir out of Bonds, weil er das [] als Byte-Set interpretiert und erst dann die Typprüfung mit dem Ziel macht
if MyRec in [1000, 2000] then // aber hier weiß er vom := , dass es ein IntegerArray werden soll, warum schaut er dann bei meinem Record nicht auch mal nach was er für Typen erwartet, schließlich wurde das vorher schon geparst //Arr := [1000, 2000]; var Arr: TArray<Integer>; if MyRec in Arr then // geht |
AW: Warum sind Klassenoperatoren nicht bissl intelligenter?
Jo, das mag unlogisch erscheinen. Ich denke allerdings, dass es halt nunmal ist, wie der Compiler intern die Operatoren verwaltet. Das Problem ist nunmal, dass
Delphi-Quellcode:
halt nicht in jedem Fall
NotEqual
Delphi-Quellcode:
entspricht.
not Equal
Eine Ungleichheit (oder eine Gleicheit) stellt man bei manchen Typen halt unterschiedlich fest, und ein generischer Vergleich wäre ja da nochmal etwas anderes (und auch nicht auf jeden Typen anwendbar, beispiel:
Delphi-Quellcode:
Jetzt stell da mal eine sinnvolle Deklaration für einen
type
TMyPoint = record X, Y: Integer; end;
Delphi-Quellcode:
-Operator auf... Geht nicht. Dennoch wären
Compare
Delphi-Quellcode:
,
Equal
Delphi-Quellcode:
,
NotEqual
Delphi-Quellcode:
, ... problemlos möglich.
GreaterThan
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:49 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