Ver Mensaje Individual
  #1  
Antiguo 29-11-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Reputación: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Sobrecarga de operadores de clase

Pues eso, aunque se supone que Delphi no soporta sobrecargar los operadores de clase como si sucede con los tipos records o registros, existe cierta sintaxis que lo hace posible, apartentemente no documentada ni oficial

En fin, no se como lo habra descubierto el que lo hizo, o de donde lo saco. La cuestion es que ha publicado dos fragmentos de codigo en GitHub, aca y aca

Sorprendentemente este codigo compila, funciona y no hay fugas de memoria, en Delphi 2010 y Delphi 10.1 Berlin, asi que supongo que "la compatibilidad se mantiene" en todas las versiones del medio.

Código Delphi [-]
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes;

type
  TStringListHelper = class helper for TStringList
  public
    class function &&op_In(const Value: string; Target: TStringList): Boolean; static;
    class function &&op_LogicalOr(A, B: TStringList): TStringList; static;
  end;

class function TStringListHelper.&&op_In(const Value: string; Target: TStringList): Boolean;
begin
  Result := Target.IndexOf(Value) <> -1;
end;

class function TStringListHelper.&&op_LogicalOr(A, B: TStringList): TStringList;
begin
  if A <> nil then
    Result := A
  else
    Result := B;
end;

procedure Test;
var
  StringListA, StringListB, StringListC: TStringList;
begin
  StringListA := nil;
  StringListB := TStringList.Create;
  try
    StringListB.Add('Hola mundo');
    StringListC := StringListA or StringListB; // -> StringListC apunta al mismo objeto que StringListB
    Writeln('StringListB.Text: ' + StringListB.Text); // imprime hola mundo
    Writeln('StringListC.Text: ' + StringListC.Text); // imprime hola mundo
    Writeln(BoolToStr(StringListB = StringListC, True)); // imprime True
    Writeln(BoolToStr('Hola mundo' in StringListB, True)); // imprime True
    Writeln(BoolToStr('blabla' in StringListB, True)); // imprime False
  finally
    StringListB.Free;
  end;
end;

begin
  ReportMemoryLeaksOnShutdown := True;
  try
    Test;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Me parece algo realmente poderoso y peligroso al mismo tiempo, no he podido ordenar mis ideas por el momento

Realmente algo como esto si que es util para escribir codigo mas elegante y sencillo. Muchas veces se emplea el uso de records como envolturas de clases o tipos primitivos ya que ellos son los unicos con los que se pueden sobrecargar los operadores; pero esto lo lleva a otro nivel

De hecho es posible hasta con genericos como se puede ver en el codigo del autor
Responder Con Cita