Clase genérica para convertir una enumeración en cadena y viceversa

Una de las cosas que siempre olvido como hacer, y por lo mismo me toca hacer una búsqueda en Google para volver a escribir el código necesario, es como convertir una enumeración en un string y viceversa (EnumToStr, StrToEnum).

Esto es, primero, porque tradicionalmente hay que escribir una rutina distinta para cada tipo de enumeración que nos interesa, o peor aún, escribir una llamada directamente a GetEnumName/GetEnumValue, que son las que hacen el trabajo sucio.

También esto se debe, en parte, porque hasta ahora no se me había ocurrido la idea de valerme de los genéricos para tener un trozo de código que sea re-utilizable y meter mi rutina en alguna biblioteca de las que suelo tener a mano mientras escribo código.

Ya con la idea, y luego de algún esfuerzo, escribí la clase que ahora les comparto, pero primero, veamos su uso, que vendría a ser, por ejemplo:

begin
  Memo1.Lines.Add(
    TEnumConverter<TAlign>.ToString(Self.Align));
end;


La idea básica es muy simple, y creo que el código habla por si solo. La ventaja es que puedes utilizarla con cualquier enumeración; incluyendo, claro está, las que tu mismo hayas definido, por ejemplo:

interface
type
  TMyEnum = (meValue1, meValue2, meValue3, meValue4);

implementation

procedure TForm1.Button1Click(Sender: TObject);
var
  MyEnum: TMyEnum;
begin
  MyEnum := meValue3;
  Memo1.Lines.Add(
    TEnumConverter<TMyEnum>.ToString(MyEnum));
end;

La clase TEnumConverter<T>

Sin más, te dejo entonces la unidad que define la clase. También puedes descargarla: UEnumConverter.pas

//------------------------------------------------------------------------------
//
// author: jachguate
//         https://jachguate.wordpress.com
//
// Disclaimer
//
// This code is provided "as is" without express or implied warranty of any
// kind
//
// The author disclaims all warranties with regard to this source code,
// including all implied warranties of merchantability and fitness for
// a particular purpose. I no event shall the author be liable for any
// special, indirect, incidental or consequential damages, or any damages
// whatsoever resulting from loss of use, data or profits, whether in an
// action of contract, negligence or other tortious action, arising out
// or in connection with the use, misuse or performance of this source code.
//
// You use it at your own risk
//
// This code is distributed free of charge.
//
// Attribution and beer is not required, but highly appreciated.
//
//------------------------------------------------------------------------------

unit UEnumConverter;

interface

type
  TEnumConverter<T> = class
    class function ToString(Value: T): string; reintroduce;
    class function FromString(const Value: string): T;
  end;


implementation
uses TypInfo;

{ TEnumConverter<T> }

class function TEnumConverter<T>.FromString(const Value: string): T;
var
  Res: Byte;
begin
  Assert(SizeOf(T) = SizeOf(Res), 'Size of source and dest varies in TEnumConverter<T>.FromString');
  Res := GetEnumValue(TypeInfo(T), Value);
  Move(Res, Result, SizeOf(T));
end;

class function TEnumConverter<T>.ToString(Value: T): string;
var
  Val: Byte;
begin
  Assert(SizeOf(T) = SizeOf(Val), 'Size of source and dest varies in TEnumConverter<T>.ToString');
  Move(Value, Val, SizeOf(Value));
  Result := GetEnumName(TypeInfo(T), Val);
end;


end.

Limitaciones

  • La clase únicamente soporta enumeraciones de 1 byte de tamaño. Es decir, que no tengan más de 256 elementos (o con ordinalidad mayor a 255 si se ha asignado explicitamente)
  • Dado que hace uso de genéricos, la clase solamente compila en Delphi 2009 o superior

¿Te gusta el contenido?

4 Respuestas a “Clase genérica para convertir una enumeración en cadena y viceversa

  1. Genial articulo Juan, muchas gracias por compartir todo ese conocimiento con nosotros🙂

  2. Pingback: Generic class to convert a enum to string and viceversa | jachguate's blog

  3. Genial aporte Juan… me pasa como a ti, siempre tengo que buscar como se hacen las conversiones entre enumerados. Pero eso se acabo… con tu clase🙂🙂

    Permitirme que deje aquí una pequeña mejora, para futuros navegantes:

    TEnumConverter = class
    public
    class function At(Value: T): String; overload;
    class function At(const Value: String): T; overload;

    class function ToString(Value: T): string; reintroduce;
    class function FromString(const Value: string): T;
    end;

    class function TEnumConverter.At(Value: T): String;
    begin
    Result := TEnumConverter.ToString(Value);
    end;

    class function TEnumConverter.At(const Value: String): T;
    begin
    Result := TEnumConverter.FromString(Value);
    end;

  4. Pingback: Cocosistemas.com. Diego Muñoz. Informático Freelance. » Blog Archive » Semana 17 febrero 2014 – 23 febrero 2014

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s