Ver Mensaje Individual
  #12  
Antiguo 15-06-2015
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Reputación: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
elrayo76,

Cita:
Empezado por elrayo76
...necesito es ver como se puede hacer para pasar por parámetro en una función un enumerado genérico...similar a lo que permite C# (System.enum)...
Cita:
Empezado por elrayo76
...Lo que quiero hacer es poder pasar a la función solamente uno de los datos de cualquiera de todos los enumerados que pueda tener...
Cita:
Empezado por elrayo76
...Lo que quiero hacer es poder obtener el nombre del dato del enumerado que se le pasa como parámetro a la función y no el valor del mismo...
Cita:
Empezado por elrayo76
...estoy usando Delphi XE8...Windows 7 de 64 bits...


Revisa este código:
Código Delphi [-]
unit Unit1;

interface

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

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

  TEnum = record
  public
    class function AsString< T >(EnumValue : T): String; Static;
    class function AsInteger< T >(EnumValue : T): Integer; Static;
  end;

  TEnumA = (A1, A2, A3, A4, A5);
  TEnumB = (B1, B2, B3, B4, B5);
  TEnumC = (C1, C2, C3, C4, C5);
  TEnumD = (D1, D2, D3, D4, D5);
  TEnumE = (E1, E2, E3, E4, E5);

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Obtiene el nombre del tipo enumerado genérico
class function TEnum.AsString< T >(EnumValue : T) : String;
begin
   Result := GetEnumName(TypeInfo(T), AsInteger(EnumValue));
end;

// Obtiene el valor del tipo enumerado genérico
class function TEnum.AsInteger< T >(EnumValue : T) : Integer;
begin
   case Sizeof(T) of
      1 : Result := pByte(@EnumValue)^;
      2 : Result := pWord(@EnumValue)^;
      4 : Result := pCardinal(@EnumValue)^;
   end;
end;

// Obtiene el nombre y valor de un tipo enumerado por medio de Genéricos
procedure TForm1.Button1Click(Sender: TObject);
begin

   MessageDlg(Format('EnumValue %s = %d',[TEnum.AsString< TEnumA >(A1), TEnum.AsInteger< TEnumA >(A1)]),mtInformation,[mbOK],0);
   MessageDlg(Format('EnumValue %s = %d',[TEnum.AsString< TEnumE >(E5), TEnum.AsInteger< TEnumE >(E5)]),mtInformation,[mbOK],0);

end;

end.
El código anterior en Delphi XE7 sobre Windows 7 x32, Permite obtener el nombre y valor de un tipo enumerado por medio de un tipo genérico, como se muestra en la siguiente imagen:



Notas:

1- El código esta basado en un ejemplo del Capítulo 3 (Understanding Generics) del libro Coding in Delphi de Nick Hodges.

2- Los tipos genéricos en Delphi no cuentan por el momento de un constraint que verifique que el tipo pasado corresponda a un tipo enumerado.

3- Hasta donde entiendo, no existe en Delphi el equivalente a System.enum de C#.

4- El código propuesto fue probado en Delphi XE4 bajo Windows 7 Professional x64, funcionando correctamente según lo esperado.

5- Si se le asignan valores a la enumeración, el método TEnum.AsInteger< T > falla, funciona correctamente con los valores por default de la enumeración.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 15-06-2015 a las 17:46:14.
Responder Con Cita