Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Error al aplicar HELPER sobre varios TARRAY (https://www.clubdelphi.com/foros/showthread.php?t=96223)

bucanero 12-05-2023 10:19:20

Error al aplicar HELPER sobre varios TARRAY
 
Hola a todos!!

Me estoy encontrando con un problema al usar helper sobre ciertas estructuras de datos, y no se si es un error mío en la forma de aplicar los helpers, o un error de la versión de delphi, detallo el problema:

Con la siguiente estructura de datos y helper todo funciona correctamente y al pulsar el botón ejecuta su proceso sobre cada estructura de datos, y hasta aquí todo correcto:

Código Delphi [-]
type
  TDatoA = record
    A: integer;
  end;

  TDatoB = record
    B: integer;
  end;

  /// 1.)
  TArrayA = Array of TDatoA;
  TArrayB = Array of TDatoB;

  TArrayAHelper = record helper for TArrayA
    procedure Proces_A;
  end;

  TArrayBHelper = record helper for TArrayB
    procedure Proces_B;
  end;

procedure TForm2.Button1Click(Sender: TObject);
var
  A: TArrayA;
  B: TArrayB;
begin
  /// ...
  A.Proces_A;
  B.Proces_B;
end;

Pero si los array de datos en vez de estar definido como en la forma 1 los defino a través de la estructura TArray que internamente se supone que es identico:

Código:

  /// 2.)
  TArrayA = TArray<TDatoA>;
  TArrayB = TArray<TDatoB>;

entonces me aparece un error de compilador indicando:
[dcc32 Error] Unit2.pas(61): E2003 Undeclared identifier: 'Proces_A'

El error básicamente es similar a cuando a una estructura de datos se le pretende asignar varios helpers distintos, pero en este ejemplo concreto son dos estructuras de datos distintas.

La solución pasa por no usar TARRAY, pero ¿realmente es un error de uso de HELPERS? o ¿es un bugs de delphi?

Neftali [Germán.Estévez] 12-05-2023 11:44:51

A mi esto me compila y se ejecuta perfectamente en Delphi 11.2 Patch 1

NOTA: No uso la etiqueta de Delphi, porque parece que no gestiona bien los símbolos de MayorQue y MenorQue de los genéricos.

Código:

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TDatoA = record
    A: integer;
  end;

  TDatoB = record
    B: integer;
  end;

  /// 2.)
  TArrayA = TArray<TDatoA>;
  TArrayB = TArray<TDatoB>;


  TArrayAHelper = record helper for TArrayA
    procedure Clear;
  end;

  TArrayBHelper = record helper for TArrayB
    procedure Clear;
  end;

  TForm3 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    A: TArrayA;
    B: TArrayB;
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
begin
  /// ...
  A.Clear;
  B.Clear;
end;

{ TArrayAHelper }

procedure TArrayAHelper.Clear;
begin
  var len:integer := Length(Self);
  // form3.Memo1.Lines.Add('Longitud=' + len.ToString);
  for var i:integer := 0 to len-1 do
    Self[i].A := 0;
end;

{ TArrayBHelper }

procedure TArrayBHelper.Clear;
begin
  var len:integer := Length(Self);
  // form3.Memo1.Lines.Add('Longitud=' + len.ToString);
  for var i:integer := 0 to len-1 do
    Self[i].B := 0;
end;


bucanero 12-05-2023 12:52:35

Hola Neftali, gracias por responder!!

Con el ejemplo tal y como tu lo has puesto, con el mismo nombre del procedimiento para ambas estructuras, entonces si se compila y ejecuta, pero me pasan varias cosas raras:
- si a las funciones les pongo para que muestre un mensaje e identificar el procedimiento que se esta ejecutando, siempre se ejecuta el proceso de la estructura B y nunca el de la estructura A.
- Si a las estructuras les meto datos, Y ambas estructura son idénticas, entonces los datos si los limpia en ambas, pero si a la estructura A le pongo otra variable por ejemplo un string para que no sean identicas, entonces la estructura A ya no la limpia.
Código Delphi [-]
procedure TArrayAHelper.Clear;
begin
  MessageDlg('TArrayAHelper.Clear', mtInformation, [mbOK], 0);
  ...
end;

{ TArrayBHelper }
procedure TArrayBHelper.Clear;
begin
  MessageDlg('TArrayBHelper.Clear', mtInformation, [mbOK], 0);
  ...
end;

Y si en los helpers a los procesos los llamo de distinta forma para cada estructura, entonces obtengo el mismo error inicial

Código Delphi [-]
  TArrayAHelper = record helper for TArrayA
    procedure ClearA;
  end;

  TArrayBHelper = record helper for TArrayB
    procedure ClearB;
  end;
el error entonces es:
[dcc32 Error] Unit2.pas(69): E2003 Undeclared identifier: 'ClearA'

Neftali [Germán.Estévez] 15-05-2023 08:39:05

1 Archivos Adjunto(s)
No se, a mi sí me ejecuta los procedimientos correctos y me diferencia entre el A y el B.
Te adjunto la imagen y el proyecto completo, para que lo compares.


bucanero 15-05-2023 16:59:44

Gracias Neftali por el tiempo dedicado!!

En mi delphi (xe7) con tu proyecto sigo teniendo el problema, imagino que será algo que no esta fino de mi instalación.

Intentare ver como solucionarlo, y de nuevo gracias por el tiempo dedicado!!

Neftali [Germán.Estévez] 15-05-2023 17:03:31

Cita:

Empezado por bucanero (Mensaje 551472)
Gracias Neftali por el tiempo dedicado!!
En mi delphi (xe7) con tu proyecto sigo teniendo el problema, imagino que será algo que no esta fino de mi instalación.
Intentare ver como solucionarlo, y de nuevo gracias por el tiempo dedicado!!

Es posible que sea un error y esté corregido en las últimas versiones.
Yo lo he probado con una 11 (no se si lo había comentado).


La franja horaria es GMT +2. Ahora son las 07:53:26.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi