Pregunta

Tiendo a usar TStringList de Delphi para la manipulación de texto, así que escribo muchos procedimientos / funciones como:

var
  TempList: TStringList;
begin
  TempList:= TStringList.Create;
  try
    // blah blah blah do stuff with TempList   


  finally
    TempList.Free;
  end;
end;

Sería bueno cortar la creación y la liberación de una clase de utilidad tan común.

Dado que ahora tenemos registros con métodos, ¿es posible ajustar una clase como TStringList en un Grabar para poder tener:

var
  TempList: TRecordStringList;
begin
  // blah blah blah do stuff with TempList   


end;
¿Fue útil?

Solución

Es posible. Cree una interfaz que exponga los métodos / objetos que desee:

type
  IStringList = interface
    procedure Add(const s: string); // etc.
    property StringList: TStringList read GetStringList; // etc.
  end;

Implemente la interfaz y haga que ajuste una TStringList real:

type
  TStringListImpl = class(TInterfacedObject, IStringList)
  private
    FStringList: TStringList; // create in constructor, destroy in destructor
    // implementation etc.
  end;

Luego implemente el registro:

type
  TStringListRecord = record
  private
    FImpl: IStringList;
    function GetImpl: IStringList; // creates TStringListImpl if FImpl is nil
                                   // returns value of FImpl otherwise
  public
    procedure Add(const s: string); // forward to GetImpl.Add
    property StringList: TStringList read GetStringList; // forward to
                                                         // GetImpl.StringList
    // etc.
  end;

El hecho de que haya una interfaz dentro del registro significa que el compilador manejará el recuento de referencias automáticamente, llamando a _AddRef y _Release a medida que las copias se crean y destruyen, por lo que la administración de por vida es automática. Esto funciona para objetos que nunca contendrán una referencia a sí mismos (creando un ciclo): el recuento de referencias necesita varios trucos para superar los ciclos en el gráfico de referencia.

Otros consejos

Si tiene la suerte de haberse actualizado a Delphi 2009, consulte El trabajo de Barry con punteros inteligentes .

TSmartPointer<T: class> = record
strict private
  FValue: T;
  FLifetime: IInterface;
public
  constructor Create(const AValue: T); overload;
  class operator Implicit(const AValue: T): TSmartPointer<T>;
  property Value: T read FValue;
end;

Son geniales, pero requieren métodos genéricos y anónimos. Si no ha actualizado a Delphi 2009 , ¡hágalo ahora! Especialmente mientras ofrecen su BOGO special . También obtienes el Manual para desarrolladores de Delphi gratis de Marco solo por descargando la versión de prueba . Ya compré una copia también.

Ya hay otro ejemplo implementado en CC .

  

StringList es lo mismo que TStringList excepto que es un valor   tipo. No tiene que ser creado, destruido o puesto dentro   intentar / finalmente. El compilador lo hace por usted. Existen   prácticamente no hay sanciones especiales de rendimiento para que estas funcionen:

var 
  strings: StringList;
  astr: string;
begin
  strings.Add('test1');
  strings.Add('test2');
  aStr := string(strings);
  RichEdit.Lines.AddStrings(strings);
end;
     

El código se puede usar como plantilla para ajustar cualquier TObject como un tipo de clase de valor.

Ya tiene todo para una TStringList expuesta para usted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top