Использование определенной ссылки на тип класса в конструкторе атрибутов Delphi - PullRequest
6 голосов
/ 02 апреля 2012

Поскольку Delphi не может обрабатывать атрибуты перечислимых значений, я попробовал другой подход.TMyEnum - это мое перечисление.Класс TMyEnumLabelProvider предоставляет нужные мне метки.Я связываю enum-тип с атрибутом с его labelprovider.Это не компилируется однако.Я не могу полностью определить провайдера, прежде чем ссылаться на его класс, так как он использует TMyEnum в одном из своих методов.

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;

Любые идеи о том, как сделать это правильно.Сейчас я обхожу себя, объявляя GetLabel (MyEnum: integer), но, очевидно, я предпочитаю быть строгим типом.

Заранее спасибо.

1 Ответ

2 голосов
/ 06 декабря 2012

Самое простое решение - использовать статический массив строк для хранения меток, как определено ниже. затем вы можете просто проиндексировать массив, используя enum, чтобы получить требуемую метку.

type
  TMyEnum = (MyEnum0, MyEnum1, MyEnum2);

const
  EnumLabels : array[TMyEnum] of string = ('MyEnumLabel0', 'MyEnumLabel1', 'MyEnumLabel2'); 
...