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?
- Mantente en sintonía:
- Suscribete a las notificaciones por correo electrónico
- Agrega el feed RSS a tu sindicador favorito.
- Sígueme en twitter: @jachguate
- ¡Participa!, deja un comentario en la entrada, sugiere un tema sobre el que te gustaría leer en el blog. ¡Las críticas —constructivas— son bienvenidas!
Genial articulo Juan, muchas gracias por compartir todo ese conocimiento con nosotros 🙂
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;