Autor Beitrag
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 09.01.11 20: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:

ausblenden 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.

ausblenden 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:

ausblenden 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;


// Achtung Nur ein Code-Schnipsel!!!

// Zuweisung bei einfachen Variablen:
  s := WennDann(n>0,'größer Null','nicht größer Null');  
  t := WennDann(Frage('Uhrzeit ?'),time,date);

// Zuweisung bei Nachfolgern von TObject:

  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:

ausblenden 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 user profile iconMartok: 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 20:41, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 09.01.11 20: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:
ausblenden 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 20:50, insgesamt 2-mal bearbeitet

Für diesen Beitrag haben gedankt: elundril
Tranx Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 09.01.11 20: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 21:23, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 09.01.11 20:54 
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
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).

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
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" :D).
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 09.01.11 21:40 
Ich hab das mal in Open Source Units verschoben, auch wenns nur ein Fragment ist.
Passt aber besser als AOA ;)

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
habe es aber vor ein paar Jahren auch oft benutzt. Wie auch den Konditionaloperator in Java (noch "schöner" :D).
Du solltest NIEMALS ein JavaScript von mir lesen, das ist voll davon :)

_________________
"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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Sa 05.03.11 18: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).

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 05.03.11 19: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 06.03.11 01: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>... :mrgreen:




user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Ü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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: So 06.03.11 10:16 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Ü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#.


Trotzdem cooler Operator (Ich habe ihn nur leider noch nie in einem C#-Programm gesehen :oops: ).
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: So 06.03.11 12:21 
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden 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

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
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.