Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using specific class type reference in Delphi attribute-constructor

As Delphi cannot handle attributes on enum-values, I tried another approach. TMyEnum is my enum. Class TMyEnumLabelProvider provides the labels I need. I link the enum-type with an attribute to its labelprovider. This doesn't compile however. I cannot define the provider fully before referencing its classtype since it uses TMyEnum in one of its methods.

TEnumLabelProviderCallback = procedure(Context: TObject; 
                                       Index: integer; 
                                       const Name: string) of object;

TEnumLabelProvider = class abstract
public
    procedure Iterate(Context: TObject; 
                      Callback: TEnumLabelProviderCallback); virtual; abstract;
end;

TEnumLabelProviderClass = class of TEnumLabelProvider;

TEnumLabelProviderAttribute = class(TCustomAttribute)
private
    FProviderClass: TEnumLabelProviderClass;
public
    constructor Create(ProviderClass: TEnumLabelProviderClass);
    property ProviderClass: TEnumLabelProviderClass read FProviderClass;
end;

TMyEnumLabelProvider = class;

{$SCOPEDENUMS ON}

[TEnumLabelProvider(TMyEnumLabelProvider)]
TMyEnum = (MyEnum0,
           MyEnum1,
           MyEnum2);
{$SCOPEDENUMS OFF}

// This is where the compilation fails.....
TMyEnumLabelProvider = class(TEnumLabelProvider)
public
    class function GetLabel(MyEnum: TMyEnum): string;
    procedure Iterate(Context: TObject; Callback: TEnumLabelProviderCallback); override;
end;

Any ideas on how to do this properly. For now I workaround by declaring GetLabel(MyEnum: integer), but obviously I prefer being type strict.

Thanks in advance.

like image 209
Christiaan ten Pas Avatar asked Apr 02 '12 08:04

Christiaan ten Pas


1 Answers

The simplest solution is to use a static array of string to store the labels as defined below. you can then simply index the array using the enum to get the label required.

type
  TMyEnum = (MyEnum0, MyEnum1, MyEnum2);

const
  EnumLabels : array[TMyEnum] of string = ('MyEnumLabel0', 'MyEnumLabel1', 'MyEnumLabel2'); 
like image 65
Mike Taylor Avatar answered Nov 01 '22 02:11

Mike Taylor