IIF

Quem já programou em Clipper e Visual Fox Pro deve lembrar da função IIF. Esta função simplesmente aceitava três parâmetros, um booleano, ou condição, e dois valores, caso verdadeiro e caso falso.
Ela era interessante porque substituia (em partes) o operador ternário ?: do C e poderia ser usada em expressões para se somar ou concatenar o valor correto dependendo da condição.
Ela servia para substituir um if ... else e uma variável temporária colocando tudo na mesma linha.

O seu formato era:

iif(condição, valor se verdadeiro, valor se falso): valor;

Ela retornava um valor que seria do mesmo tipo do segundo e terceiro argumento.

É possível criar inúmeras variantes dessa função, tanto no Lazarus como no Delphi. Usando variants poderiamos  criar uma vertente da função que funcionaria para qualquer tipo de dado primitivo.

Mas o Delphi é ainda mais flexível porque hoje temos Generics e o tipo TValue, que são mais flexíveis ainda. Com Generics, Variants e sobrecarga de operadores podemos utilizar sim qualquer tipo de valor, classes, objetos instanciados e assim por diante. Além disso, com expressões lambda e funções "inline" podemos inclusive colocar função/execução de código no IIF o que extrapola o seu objetivo de substituir o operador ternário. Ele se torna realmente um if...else. Esse tipo de coisa poderíamos fazer nas versões antigas do Delphi e no Lazarus apenas com ponteiros para métodos.

Esse código abaixo mostra um exemplo da função IIF e seu uso, inclusive com generics nas versões modernas do Delphi.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function iif(condicao: Boolean; ValorVerdadeiro, ValorFalso: T): T;

implementation

{$R *.dfm}

function iif(condicao: Boolean; ValorVerdadeiro, ValorFalso: T): T; 
begin
  if condicao then
    Result := ValorVerdadeiro
  else
    Result := ValorFalso;
end;

function iif(condicao: Boolean; ValorVerdadeiro, ValorFalso: string): string;
begin
  if condicao then
    Result := ValorVerdadeiro
  else
    Result := ValorFalso;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  a,b, resultado: string;
  x,y: integer;
  debita: boolean;
begin

  a := 'Clube';
  b := 'Delphi';

  x := 1;
  y := 2;

  debita := true;
  resultado:= inttostr(iif(debita, y-1, y+1));
  ShowMessage(resultado);

  debita := false;
  resultado:= inttostr(iif(debita, y-1, y+1));
  ShowMessage(resultado);

  resultado:= iif(x=y, 'x é igual a y', 'x é diferente de y');
  ShowMessage(resultado);

  x := y;
  resultado:= iif(x=y, 'x é igual a y', 'x é diferente de y');
  ShowMessage(resultado);

  resultado:= iif((a<>'')and (b<>''), a + ' ' + b , 'um dos dois é vazio');
  ShowMessage(resultado);

  a := '';
  resultado:= iif((a<>'')and (b<>''), a + ' ' + b , 'um dos dois é vazio');
  ShowMessage(resultado);

  resultado:= iif(a=b, 'a e b são iguais', 'a e b são diferentes');
  ShowMessage(resultado);

end;

end.



Aqui criamos apenas duas versões, uma com generics (que funcionará para tudo) e uma com strings. Poderíamos criar com variants ou qualquer outra coisa.

Uma alteração interessante que pode ser feita também é declarar os argumentos/parâmetros das funções como const, assim eles não poderão ser temporariamente modificados por expressões lambda ou código dentro do corpo de IIF.


function iif(const condicao: Boolean; const ValorVerdadeiro, ValorFalso: T): T;

{...}

function iif(const condicao: Boolean; const ValorVerdadeiro, ValorFalso: T): T; 
begin
  if condicao then
    Result := ValorVerdadeiro
  else
    Result := ValorFalso;
end;


Espero que seja útil para todos. Pelo menos saudosista é ;)

Comentários

Postagens mais visitadas deste blog

Detectar o encoding de um arquivo para não corromper ao transformá-lo

erro "ora-12154: tns: não foi possível resolver o identificador de conexão especificado"

Quebras de linha no Delphi 2010