Warum kann der Compiler nicht auch mal etwas Intelligenz zeigen und den impliziten Cast benutzen, anstatt beim
if List[0] = 0 then
aufzugeben?
Andersrum geht
if 0 = List[0] then
zum Glück auch nicht, obwohl der Compiler dort ja schon weiß, dass der Vergleich einen
Integer ordinalen Typen haben möchte.
Delphi-Quellcode:
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;
Oder hier einfach mal die Reihenfolge optimaler anpassen?
Delphi-Quellcode:
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?
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.
Und das mit den Settern läst sich dadurch verhindern, dass der Record keine Setter bekommt. (implizite Casts als Zuweisung funktionieren erstaunlicher Weise)