Toon posts:

[Delphi] IIf-statement

Pagina: 1
Acties:
  • 149 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
In C/Java/VB kent men iets als een IIf (Voorwaarde % TruePart ? FalsePart, o.i.d.)

Nou heb ik deze ook in Delphi gemaakt maar ik kon deze op 2 manieren implementeren met ieder z'n eigen voor- en nadelen.

Methode A: Variants
code:
1
2
3
4
5
6
7
8
9
10
11
12
function IIf(const Condition: Boolean; const TruePart, FalsePart: Variant): Variant;
begin
  if Condition then
    Result := TruePart
  Else
    Result := FalsePart;
end;

procedure Test;
begin
  ShowMessage(IIf(1=2, 'Komt niet tevoorschijn', 'Klopt als een zwerende vinger'));
end;

Deze methode heeft als voordeel dat er voor de programmeur niet gecast hoeft te worden maar lijkt me behoorlijk traag aangezien 128-bits(?) variabelen worden gebruikt. Tevens zullen niet alle soorten variabelen naar Variants (bijv. Objecten) gecast kunnen worden.

Methode 2: pointers
code:
1
2
3
4
5
6
7
8
9
10
11
12
function IIf(const Condition: Boolean; const TruePart, FalsePart: Pointer): Pointer;
begin
  if Condition then
    Result:=TruePart
  Else
    Result:=FalsePart;
end;

procedure Test;
begin
  ShowMessage(PChar(IIf(2=2, PChar('Klopt als een zwerende vinger'), PChar('Foutje'))));
end;

Voordeel is dat er veel minder door de app. gecast hoeft te worden en er geen trage variants worden gebruikt. Tevens is iedere variabele te gebruiken. Nadeel is wel dat de programmeur veel meer moet casten.

Zijn er nog meer/betere manieren?

  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Ik ben van mening dat je niet veel tijd hoeft te stoppen in het optimaliseren van procedures die maar 1x (of een paar keer) worden uitgevoerd.

Gebruik je dus zo af en toe een IIF, gebruik dan de methode met variants.

Gebruik je echter erg vaak een IIF (paar duizend keer per seconde oid), en je wilt de boel echt snel houden, dan zou je zelfs beter de hele IIF kunnen vergeten (functie aanroep kost ook kloktikken), en gewoon een if-then-else-statement kunnen gebruiken.

Siditamentis astuentis pactum.


Verwijderd

zo doe ik het:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function iif( const Value: Boolean; const ResultIfTrue: string; const ResultIfFalse: string ) : string; overload;
begin
  if Value then
    Result := ResultIfTrue
  else
    Result := ResultIfFalse;
end;

function iif( const Value: Boolean; const ResultIfTrue: dword; const ResultIfFalse: dword ) : dword; overload;
begin
  if Value then
    Result := ResultIfTrue
  else
    Result := ResultIfFalse;
end;

function iif( const Value: Boolean; const ResultIfTrue: integer; const ResultIfFalse: integer ) : integer; overload;
begin
  if Value then
    Result := ResultIfTrue
  else
    Result := ResultIfFalse;
end;

dus met overloads, en dan eventueel een met een pointer of variant erbij, dan zoekt de compiler zelf de beste uit.

oja, templates, maar ja, dat kan weer niet in Delphi :(

Verwijderd

Topicstarter
Op dinsdag 26 februari 2002 16:26 schreef Varienaja het volgende:
Ik ben van mening dat je niet veel tijd hoeft te stoppen in het optimaliseren van procedures die maar 1x (of een paar keer) worden uitgevoerd.

Gebruik je dus zo af en toe een IIF, gebruik dan de methode met variants.

Gebruik je echter erg vaak een IIF (paar duizend keer per seconde oid), en je wilt de boel echt snel houden, dan zou je zelfs beter de hele IIF kunnen vergeten (functie aanroep kost ook kloktikken), en gewoon een if-then-else-statement kunnen gebruiken.
Ok, maar als je je nou bedenkt dat een floating-point variabele casten naar een variant en weer terug naar floating-point voor behoorlijk wat problemen kan zorgen dan lijkt me manier 2 idd. beter.
Idd. zou bij code optimalisatie soms een normaal if-then-else beter zijn.

Kvind het gewoon een mooie(re) manier van proggen (geneste if-statements om ze zo maar te noemen). Eveneens vind ik ++i, i++, for(int i=0;i<10;i++) veel mooier. Misschien dat er daarom een nog wel veel slimmere manier is om zo'n geneste if-statement in Object Pascal te realiseren.

Verwijderd

Topicstarter
Op dinsdag 26 februari 2002 16:30 schreef deur het volgende:
zo doe ik het:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function iif( const Value: Boolean; const ResultIfTrue: string; const ResultIfFalse: string ) : string; overload;
begin
  if Value then
    Result := ResultIfTrue
  else
    Result := ResultIfFalse;
end;

function iif( const Value: Boolean; const ResultIfTrue: dword; const ResultIfFalse: dword ) : dword; overload;
begin
  if Value then
    Result := ResultIfTrue
  else
    Result := ResultIfFalse;
end;

function iif( const Value: Boolean; const ResultIfTrue: integer; const ResultIfFalse: integer ) : integer; overload;
begin
  if Value then
    Result := ResultIfTrue
  else
    Result := ResultIfFalse;
end;

dus met overloads, en dan eventueel een met een pointer of variant erbij, dan zoekt de compiler zelf de beste uit.

oja, templates, maar ja, dat kan weer niet in Delphi :(
Dit is idd. ook een goede manier. Alleen om nou voor ieder type een overload te gaan maken lijkt me ook weer ietwat overdreven.

Ik heb nog een manier gevonden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
function IIf(const Condition: Boolean; const TruePart, FalsePart): Pointer;
begin
  if Condition then
    Result := @TruePart
  else
    Result := @FalsePart;
end;

procedure Test;
begin
  ShowMessage(String(IIf(X=Y, 'Waar', 'Niet waar')));
end;

Deze methode compileert echter niet altijd goed:
code:
1
IIf(True, 1, 2);

Compileert niet, evenals:
code:
1
IIf(True, '1', '2');

Wat vreemd genoeg wel compileert:
code:
1
IIf(True, 'Test', 'Bla');

Wat ook compileert:
code:
1
2
3
4
5
var
  I, J: Integer;
begin
  IIf(False, I, J);
end;

Dus lijkt deze methode me ook niet de juiste aangezien deze nogal selectief met de parameter omgaat.

Verwijderd

Topicstarter
Het overloaden is ook geen suc6 al zeg ik het zelf. Ik denk zelf dat pointers nog het beste/snelste resultaat geven.
Pagina: 1