![]() |
Delphi-Version: XE8
Wirkliche Unterschiede??
Hi zusammen
In einem der in Delphi enthaltenen Demos gibt es eine einzige Prozedure, die in einem Case..of-Block zwischen allen unter Delphi möglichen DBs unterscheidet. In den den einzelnen Selektorblöcken befinden sich eine ganze Menge Konstrukte wie das unten nicht auskommentierte. Die ganzen with..do begin..end-Konsttrukte benötigen insgesamt geschätzt wohl ebensoviel Platz wie die eigentlichen Anweisungen, was die komplette Prozedur sagenhaft aufbläht. Um etwas mehr Übersichtlichkeit zu erreichen, habe ich unter einem der Selektoren diese with-Konstrukte durch solche zu ersetzen, wie sie der ausgeklammerte Block widergibt - und prompt meckerte Delphi wegen unbekanntem Bezeichner PrecMax(zum Bleistift).
Delphi-Quellcode:
An was liegt das? Ich habe zwar eine Vermutung. Aber sowas ist letzten Endes weniger als Halbwissen. Ich selst verwende seit Jahren aus mehreren Gründen keine with do begin - Blöcke mehr.
with MapRules.Add do begin
PrecMax := 19; PrecMin := 4; SourceDataType := dtFmtBCD; TargetDataType := dtCurrency; end; // MapRules.Add(PrecMax := 2); // MapRules.Add(PrecMin := 0); // MapRules.Add(SourceDataType := dtFmtBCD); // MapRules.Add(TargetDataType := dtBoolean); Gruss Delbor |
AW: Wirkliche Unterschiede??
MapRules.Add wird wohl eine neue Instanz von irgendwas (bin gerade zu faul zum Nachsehen) zurückgeben. Von daher ist Deine Syntax schlicht falsch. Richtig müsste es dann so lauten:
Delphi-Quellcode:
var
Dings: TWasAuchImmer; begin Dings := MapRules.Add; Dings.PrecMax := 19; Dings.PrecMin := 4; Dings.SourceDataType := dtFmtBCD; Dings.TargetDataType := dtCurrency; |
AW: Wirkliche Unterschiede??
Zitat:
Aber wir bauen diese With-Anweisungen überall aus wenn wir in der Unit eh Anpassungen vornehmen. Diese with-Statements sind immer ein Quell von Überraschungen. |
AW: Wirkliche Unterschiede??
Ja, aber darum ging es ja nicht. Ich finde es lobenswert, das with zu eliminieren, wo man darauf trifft, aber man muss es dann auch syntaktisch korrekt machen.
|
AW: Wirkliche Unterschiede??
In dem Code:
Delphi-Quellcode:
Wird 4 mal ein Instanz von Irgenwas erzeugt, und in der Add-Methode jedes mal etwas anderes Übergeben.
MapRules.Add(PrecMax := 2);
MapRules.Add(PrecMin := 0); MapRules.Add(SourceDataType := dtFmtBCD); MapRules.Add(TargetDataType := dtBoolean); Zitat:
|
AW: Wirkliche Unterschiede??
Hi DeddyH
Ehrlich gesagt, war ich auch zu faul, um nachzusehen - ich ging allerdings davon aus, dass mit Add etwas einer Liste oder einer Collection hinzugefügt wird. Also müsste das, was da hinzugefügt wird, unter beiden Schreibweisen schon bekannt sein. Angenommen, Dings ist ein Object: Methoden: -Add; Propertys: -Percmax : integer; -Percmin : integer; -SourceDataType := TWasAuchImmer; -TargetDataType := TWasAuchImmer; Um nun an die Propertys Werte zuzuweisen, brauche ich doch gar keine Methode Add, sondern kann die neuen Werte direkt zuweisen:
Delphi-Quellcode:
Dings.PrecMax := 19;
Delphi-Quellcode:
Das hier lese ich so:
var
Dings: TWasAuchImmer; begin Dings := MapRules.Add; Dings.PrecMax := 19; Dings.PrecMin := 4; Dings.SourceDataType := dtFmtBCD; Dings.TargetDataType := dtCurrency; Dings ist ein Object der Klasse TWasAuchImmer Dieser Klasse wird -eine Unterklasse (Dings.Add) -ein Property oder -eine Methode zugewiesen. Letztere zwei Punkte fallen weg. Somit wäre nur eine Wertzuweisung an die Unterklasse 'Add' der Dings-Klasse möglich. Da 'PrecMax ' in der Unterklasse bekannt ist, gibts auch keinen Fehler. Aber wer nennt seine Klasse schon 'Add'?? Gruss Delbor |
AW: Wirkliche Unterschiede??
Add ist keine Klasse! Das ist eine Methode (Funktion) der Klasse, von der MapRules ist (TMapRules vermutlich). Diese Funktion gibt Dir eine Instanz zurück, und dieser Instanz weist Du nun die Werte zu.
|
AW: Wirkliche Unterschiede??
Also so wie ich die gängigen Add-Methoden kenne (bei TListView u.ä.) ist DeddyHs Variante die einzig korrekte Alternative zu dem with...do-Statement.
|
AW: Wirkliche Unterschiede??
Hi HobbyCoder
Zitat:
Delphi-Quellcode:
Oben das in der Demo angetroffene Konstrukt, unten das Konstrukt, das ich satt dessen zu verwendsen gedachte und das zu einer AV führte.
with MapRules.Add do begin
PrecMax := 19; PrecMin := 4; SourceDataType := dtFmtBCD; TargetDataType := dtCurrency; end;
Delphi-Quellcode:
Gruss
// MapRules.Add(PrecMax := 2);
// MapRules.Add(PrecMin := 0); // MapRules.Add(SourceDataType := dtFmtBCD); // MapRules.Add(TargetDataType := dtBoolean); Delbor |
AW: Wirkliche Unterschiede??
Hat sich das kompilieren lassen? Damit hätte ich jetzt nicht gerechnet.
|
AW: Wirkliche Unterschiede??
![]() |
AW: Wirkliche Unterschiede??
Zitat:
Zum zweiten, einmal ist es eine Instanz und einmal sind es 4 Instanzen. Ist für mich ein entscheidender unterschied. Zum dritten, was weiß ich denn, was in der Add-Methode steht, und welche Parameter du da überhaupt übergeben kannst, oder ob es da überladene Methoden gibt. Schau doch mal nach. Fakt ist jedenfalls, dass With..do alles mit einer Instanz mache und 4 mal x.Add() mit 4. |
AW: Wirkliche Unterschiede??
HI DeddyH
Zitat:
Delphi-Quellcode:
nicht funktionierte.
MapRules.Add(PrecMax := 2);
Daher auch meine Vermutung, dass Add eine Klasse mit dem Property PrecMax sein müsste. Aber eben: wer nennt seine Klasse schon 'Add'?? @Bernhard Geyer: Die Demo ist das program Indices aus Object Pascal\Database\FireDAC\Samples\Comp Layer\TFDQuery, falls das interessiert. Gruss Delbor |
AW: Wirkliche Unterschiede??
Jetzt mal blöd gefragt, worum geht es hier eigentlich noch?
Das Zitat:
Zitat:
|
AW: Wirkliche Unterschiede??
Hi Hobbycoder
Zitat:
Delphi-Quellcode:
Das ist definitiv immer die gleiche Instanz und auch immer die gleiche Add-Methode.
var Adresslist: TStringlist;
Adresslist.Add(xxxx); Adresslist.Add(xxxx); Adresslist.Add(xxxx); Adresslist.Add(xxxx); In einem With-Konstrukt würde ich das allerdings so schhreiben:
Delphi-Quellcode:
Nach dem Angetroffenen Konstrukt ginge dies offenbar aber auch so:
with Adresslist do begin
Add(xxxx); Add(xxxx); Add(xxxx); Add(xxxx); end;
Delphi-Quellcode:
@bra:
with Adresslist.Add do begin
y:=xxxx; y:=xxxx; fy:=xxxx; dy:=xxxx; end; Zitat:
Gruss Delbor PS: Das hier hab ich allerdings bis jetzt übersehen (Antwort 11 von Towmuz): Zitat:
|
AW: Wirkliche Unterschiede??
Delphi-Quellcode:
So oder so ähnlich dürfte die Konstellation aussehen. Der Aufruf von Add führt dazu, dass TMyItemList eine neue Instanz von TMyItem erzeugt, diese in seiner internen Liste ablegt und zurückgibt. Das bedeutet, dass mit jedem Aufruf von Add eine neue Instanz erzeugt und zurückgegeben wird. Jetzt klarer?
type
TMyItem = class ... end; TMyItemList = class ... function Add: TMyItem; end; |
AW: Wirkliche Unterschiede??
Hi DeddyH
Zitat:
Mein Fehler war offensichtlich, dass ich die Unterschiede von Collections und Listen bisher nicht kannte. Mit ersteren hab ich noch nicht wirklich aktiv gearbeitet. Gruss Delbor |
AW: Wirkliche Unterschiede??
Zitat:
Zitat:
Zitat:
Die Frage ist also, was liefert die Methode Add überhaupt zurück? Denn ich könnte ja folgendes im Sourcecode von TAddresslist schreiben:
Delphi-Quellcode:
Jetzt kannst du als AdressList.Add('Willi') ausführen,
function TAdressList.Add(Name: string): integer;
var Adress: TAdress; begin Adress: TAdress.create; Adress.Name:=Name; self.Add(Adress); Result:=self.Count-1; end; aber With AddressList.Add do Name:='Willi' hagelt es eine Exception. Würde da aber stehen:
Delphi-Quellcode:
dann könnte man so oder so arbeiten.
function TAdressList.Add(Name: string): TAdress;
var Adress: TAdress; begin Adress: TAdress.create; Adress.Name:=Name; self.Add(Adress); Result:=Adress; end; Entscheidet ist aber immer noch dass jedes Add eine neue Instanz erzeugt.
Delphi-Quellcode:
Erzeugt 4 Adresseinträge die alle Willi heißen
AdressList.Add('Willi');
AdressList.Add('Willi'); AdressList.Add('Willi'); AdressList.Add('Willi'); Aber
Delphi-Quellcode:
Erzeugt 1 Adresseinttrag der Willi heißt.
with AdressList.Add do
begin Name:='Willi'; Name:='Willi'; Name:='Willi'; Name:='Willi'; end; Es ist also entscheidend die Methode Add aussieht. Möglicherweise habe ich auch die Frage falsch verstanden. |
AW: Wirkliche Unterschiede??
Hi Hobbcoder
Zitat:
Zitat:
Die TCollectionsmethode Add erzeugt ein TCollectionItemsObject und fügt dieser der Collection hinzu. Die TStringsmethode Add fügt dem TSringsobjekt einen String oder eben auch eine Stringinstanz hinzu, erzeugt dabei allerdings kein neues Objekt (Item ist ein TString). Zitat:
Gruss Delbor |
AW: Wirkliche Unterschiede??
Das hat doch nichts mit Liste oder Collection zu tun, sondern rein damit, wie der Rückgabewert (im Bezug auf den Datentyp) der Add-Methode deklariert ist. TKlasse1 und TKlasse2 können ja beide eine Add-Methode besitzen, die aber völlig unabhängig voneinander sind und auch unterschiedliche Typen besitzen können. Anhand des Codes aus dem Ausgangsbeitrag kann es aber IMO nur so sein, dass ein komplexeres Konstrukt, d.h. entweder eine Klasseninstanz, ein Interface oder ein Record, zurückgegeben wird.
|
AW: Wirkliche Unterschiede??
Hi zusammen
@DeddyH: Zitat:
Gruss Delbor |
AW: Wirkliche Unterschiede??
Ist eine TStringList vielleicht auch eine Liste? :wink:
|
AW: Wirkliche Unterschiede??
Zitat:
|
AW: Wirkliche Unterschiede??
Zitat:
Zitat:
|
AW: Wirkliche Unterschiede??
Hi DeddyH
Zitat:
Delphi-Quellcode:
@Hobbycoder:
function TAdressList.Add(Name: string): TAdress;
var Adress: TAdress; begin Adress: TAdress.create; Adress.Name:=Name; self.Add(Adress); Result:=Adress; end; Zitat:
Okay, das müsste anders formuliert sein: Zitat:
Zitat:
Gruss Delbor |
AW: Wirkliche Unterschiede??
Wer sagt denn, dass die TAddressList von TStringList abstammt?
|
AW: Wirkliche Unterschiede??
Hi DeddyH
Zitat:
Delphi-Quellcode:
Okay,hier verwende ich eine lokale Instanz. So aus dem Stegreif heraus (ich bin mir nicht ganz sicher) müsste ich eine eigene Klasse TAddresslist deklarieren und könnte dann in deren Konstruktor die geerbte Add-Methode überschreiben.
var Adresslist: TStringlist;
Adresslist.Add(xxxx); Adresslist.Add(xxxx); Adresslist.Add(xxxx); Adresslist.Add(xxxx); Das ist definitiv immer die gleiche Instanz und auch immer die gleiche Add-Methode. Gruss Delbor |
AW: Wirkliche Unterschiede??
Jetzt wirfst Du aber alles durcheinander. Im gesamten Thread war nie von TStringList die Rede, bis Du damit angefangen hast. Die eingangs gezeigten MapRules jedenfalls sind definitiv keine TStrings oder Nachkommen davon.
|
AW: Wirkliche Unterschiede??
Hi DeddyH
Zitat:
Zitat:
Zitat:
Später hatte ich dann wegen dieses Links auf TCollection Bezug genommen und Vergleiche mit TStringlist gemacht. Denn genau diese und ihre Add-Methode waren es ja, die mich veranlasst hatten, diesen Thread zu eröffnen. Und da lag wohl auch mein Hauptfehler: Im Eingangsbeitrag hätte ich schreiben müssen, dass mit dem in Delphi vordefinierten TStringlist.Add der auskommentierte Code hätte funktionieren müssen. 'tschuldigung :( Ich hoffe, ich konnte den von mir geknüpften gordischen Knoten nun etwas lösen! Gruss Delbor |
AW: Wirkliche Unterschiede??
Alles gut :-)
Manchmal passiert das eben, dass man mehr oder weniger an einander vorbei redet. Auch ich hatte in deinem Post#15 überlesen, dass du nun das Beispiel auf TStringList geändert hattest. Ich bin immer von einer TList oder ToBjectList ausgegangen, weil ich mal angenommen habe, dass TMapRules nicht nur eine einfache StringList ist. Und das wiederum deswegen, weil sowas:
Delphi-Quellcode:
bei einer StringList so überhaupt nicht funktionieren kann.
with MapRules.Add do begin
PrecMax := 19; PrecMin := 4; SourceDataType := dtFmtBCD; TargetDataType := dtCurrency; end; |
AW: Wirkliche Unterschiede??
Nur noch mal zum Abschluss: dieses MapRules (klingt mir sehr nach FireDAC, ich schau aber trotzdem jetzt nicht nach) dürfte sehr wohl eine Liste sein, nur eben keine StringListe, sondern eine Liste von Objekten (oder auch Records oder Interfaces), die mindestens die Eigenschaften PrecMax, PrecMin, SourceDataType und TargetDataType aufweisen. Durch das "with" spart man sich die Deklaration einer eigenen Variablen, erkauft sich das dann aber auch mit schlechter les- und wartbarem Code. Die Alternative habe ich ja bereits auf der ersten Seite aufgezeigt. Und
Zitat:
|
AW: Wirkliche Unterschiede??
Hi zusammen
Auch von meiner Seite aus zum Abschluss: TMapRules, bzw TMapRule, sind tatsächlich Firedac-Konstrukte. Ich habe da mal nochmal nachgesehen und bin auch einem Link gefolgt, der TMapRule(s) beschreibt. Und da sind die Deklarationen angegeben:
@Hobbycoder: Zitat:
Ein gutes hat die Sache für mich aber doch: Ich werds wohl nicht so schnell vergessen. Auf jeden Fall, vielenDank an euch beide! Gruss Delbor |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:16 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