Autor |
Beitrag |
Tranx
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 09.01.11 19:32
Hallo Leute,
habe mich immer wieder geärgert, dass dauernd diese if .. then .. else - Konstrukte in meinem Programm auftauchen. Meist waren es nur einfache Zuweisungen der Art:
Delphi-Quelltext 1: 2: 3: 4:
| if Bedingung then Wert := a else Wert := b; |
Ich habe daher eine ganz einfache Funktion definiert, welche diese Abfrage auf eine Zeile verkürzt.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| unit Bedingung;
interface
uses SysUtils;
function WennDann(Bedingung: boolean; wenn, dann: Variant): variant; overload; function WennDann(Bedingung: boolean; wenn, dann: TObject): TObject; overload;
implementation
function WennDann(Bedingung: boolean; wenn, dann: Variant): variant; begin if Bedingung then Result := wenn else Result := dann; end;
function WennDann(Bedingung: boolean; wenn, dann: TObject): TObject; begin if Bedingung then Result := wenn else Result := dann; end;
end. |
Bei Zuweisungen einfacher Typen klappt das problemlos. Char könnte ebenfalls zugewiesen werden, ist jedoch nicht kompatibel zu Variant. Daher müsste da auch eine überladene Funktion geschrieben werden. Doch das benötigte ich nur zweimal in meinem Projekt.
Aufruf erfolgt wie folgt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| var s : string; n : longint; t : TDateTime; Tabelle, tTable1, tTable2 : TTable;
function Frage(s: string): Boolean; begin Result := (messageDlg(s, mtConfirmation, [mbYes, mbNo], 0) = mrYes); end;
s := WennDann(n>0,'größer Null','nicht größer Null'); t := WennDann(Frage('Uhrzeit ?'),time,date);
Tabelle := WennDann(Bedingung, tTable1, tTable2) as TTable; n := WennDann(Tabelle.RecordCount>0,Tabelle.RecordCount,-1); |
Dito für andere Nachfolgeklassen.
Da das Ganze eine Funktion ist, kann auch eine folgender Konstrukt erfolgen:
Delphi-Quelltext 1: 2: 3: 4: 5:
| : : List1.Items.Add(WennDann(Frage('Ist der Wert ok?'),'Wert ist ok','Wert ist nicht ok'); : : |
Vielleicht ist das für Euch auch nützlich. Zugegeben, nur ein einfaches Tool. Aber meine Programme sind dadurch wirklich etwas aufgeräumter. Moderiert von Martok: Topic aus Algorithmen, Optimierung und Assembler verschoben am So 09.01.2011 um 20:36
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
Zuletzt bearbeitet von Tranx am So 09.01.11 19:41, insgesamt 1-mal bearbeitet
|
|
jaenicke
Beiträge: 19288
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 09.01.11 19:40
Es gibt für diverse Typen bereits IfThen als Befehl.
Der deutliche Nachteil an deiner Variante ist, dass du Variants benutzt. Da diese sehr langsam sind, ist das nur geeignet, wenn es auf die Performance nicht ankommt. Wenn das aber sehr oft aufgerufen wird, ist das relativ langsam.
// EDIT:
Wobei zumindest keine Typumwandlungen notwendig sind, aber auch die Prüfungen dauern.
Deutlich besser geht das mit Generics, aber die gibt es erst ab Delphi 2009, mal so hingetippt: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| function IfThen<T>(Value: Boolean; TrueValue, FalseValue: T): T; begin if Value then Result := TrueValue else Result := FalseValue; end; |
Zuletzt bearbeitet von jaenicke am So 09.01.11 19:50, insgesamt 2-mal bearbeitet
Für diesen Beitrag haben gedankt: elundril
|
|
Tranx
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 09.01.11 19:48
Das mit der Performance ist mir schon klar. Doch bei den Anwendungen, welche ich meine, ist das eher zweitrangig.
In meiner Entwicklungsumgebung (bisher Delphi 5) habe ich wenig Alternativen.
//EDIT:
Zusätzlich kommt hier ein Effekt hinzu, der nicht zu vernachlässigen ist. Beim Debuggen hat man ja einenm Einstiegspunkt. Falls irgendwelche IF..THEN...ELSE nicht so funktionieren, wie gewünscht, sind sie einfach zu kontrollieren. Nur ein oder zwei Haltepunkte statt hunderter.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
Zuletzt bearbeitet von Tranx am So 09.01.11 20:23, insgesamt 1-mal bearbeitet
|
|
jaenicke
Beiträge: 19288
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 09.01.11 19:54
Tranx hat folgendes geschrieben : | In meiner Entwicklungsumgebung (bisher Delphi 5) habe ich wenig Alternativen. |
Außer es eben für die wichtigsten Typen einzeln zu deklarieren wie es ab Delphi 6 auch in Delphi selbst passiert ist (dort für Integer, Int64, Double und string).
Tranx hat folgendes geschrieben : | Das mit der Performance ist mir schon klar. Doch bei den Anwendungen, welche ich meine, ist das eher zweitrangig. |
Dann ist das auch in Ordnung, mir hat nur der Hinweis gefehlt, denn das ist sicher nicht jedem klar.
// EDIT:
Nebenbei: Ob es tatsächlich aufgeräumter ist, darüber lässt sich streiten. Ich verzichte mittlerweile zugunsten der Lesbarkeit (ein Befehl pro Zeile, ...) wieder auf IfThen, habe es aber vor ein paar Jahren auch oft benutzt. Wie auch den Konditionaloperator in Java (noch "schöner" ).
|
|
Martok
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: So 09.01.11 20:40
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
Jakob_Ullmann
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Sa 05.03.11 17:54
Ich finde, der ?:-Operator ist eines der sinnvollsten Dinge, die C und die Sprachen mit einer ähnlichen Syntax zu bieten haben.
Übrigens auch cool: Der ??-Operator in Vala (Weiß nicht, ob den noch andere Programmiersprachen haben, aber ich habe den bisher nur in Vala gesehen).
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| output = person ?? "<unknown>";
/* dasselbe: */
output = (person != null) ? person : "<unknown>";
/* oder eben: */
if (person != null) {
output = person;
} else {
output = "<unknown>"; } |
|
|
jaenicke
Beiträge: 19288
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 05.03.11 18:37
Ich habe den Konditionaloperator ja auch viel und gerne benutzt, aber nur weil ich da gerade erst gelernt habe und es schön fand, dass der Code so kurz war, ihn aber niemand auf Anhieb verstanden hat...
Mittlerweile möchte ich, dass andere den Code verstehen, deshalb schreibe ich lieber sauberen und übersichtlichen Code mit ausführlichen Bezeichnern usw....
|
|
Kha
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 06.03.11 00:49
<der-muss-sein>
Die Beliebtheit von ?: muss nicht unbedingt nur mit der Prägnanz des erzeugten Quellcodes zusammenhängen (und wie so oft dürfte er eher Produkt denn Ursache unübersichtlichen Codes sein), sondern kann als eine der wenigen Möglichkeiten in C-artigen Sprachen, innerhalb eines Ausdrucks Kontrollfluss zu erzeugen (wer möchte heutzutage noch Short-Circuiting-Operatoren missen?), die Sehnsucht des Programmierers nach funktionalem/deklarativem Code (derer er sich vielleicht gar nicht bewusst ist) ausdrücken. Belege für diesen Trend auch in imperativen Sprachen wären z.B. die Ausdruckstypen in Prism.
</der-muss-sein>...
Jakob_Ullmann hat folgendes geschrieben : | Übrigens auch cool: Der ??-Operator in Vala (Weiß nicht, ob den noch andere Programmiersprachen haben, aber ich habe den bisher nur in Vala gesehen). |
Stammt von C#.
_________________ >λ=
|
|
Jakob_Ullmann
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: So 06.03.11 09:16
|
|
Delphi-Laie
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: So 06.03.11 11:21
Tranx hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function WennDann(Bedingung: boolean; wenn, dann: Variant): variant; begin if Bedingung then Result := wenn else Result := dann; end;
function WennDann(Bedingung: boolean; wenn, dann: TObject): TObject; begin if Bedingung then Result := wenn else Result := dann; end;
end. | |
Die deutschen Bezeichnungen in den Funktionen sind falsch übersetzt und damit - gelinde gesagt - irritierend, genaugenommen fehleranfällig. M.E. jedenfalls fehleranfälliger als das originale if-then-else, deren hier behauptete Unübersichtlichkeit ich nicht bestätigen kann.
if- wenn, falls, sofern
then - dann, so
else - sonst, ansonsten, anderenfalls
Tranx hat folgendes geschrieben : | Ich habe daher eine ganz einfache Funktion definiert, welche diese Abfrage auf eine Zeile verkürzt. |
Wenn die Bedingung nicht allzu lang/komplex ist und der/die Befehl(e) hinter then und ggf. else ebenfalls nicht zu lang sind, die Übersichtlichkeit also gewahrt bleibt, dann packe ich derlei auch in eine Zeile bzw. dann kann man es in eine Zeile schreiben.. Einer Zusatzfunktion bedarf es also dafür nicht (unbedingt).
Ich staune, daß solche "elementaren" Befehle wie die der Verzweigung überhaupt in eine Funktion gepackt und so halbwegs substituiert werden können. Eine echte Notwendigkeit erkenne ich in dieser m.E. unnötigen Verkomplizierung allerdings nicht.
|
|
|