Delphi 2010 RTTI: изучить перечисления

Вы можете добиться чего-то подобного, используя display:block;.

См. эту скрипту: http://jsfiddle.net/R53KH/

13
задан Johan 3 October 2013 в 03:50
поделиться

5 ответов

Что-то вроде этого?

http://flet.tutsplus.com/freebies/themes/netbeans-twilets-theme/


http://nettuts.s3.cdn.plus.org/38_netBeansfreebiebie/twilight .png http://nettuts.s3.cdn.plus.org/338_netbeansforebie/twilight.pngf

-121-3414231-

Атрибуты, связанные с элементами в перечислениях, в настоящее время не хранятся в данных Win32 RTTI в исполняемый. RTTI уже несут ответственность за справедливое увеличение размера исполняемых файлов, поэтому некоторые линии должны были быть нарисованы где-то. Атрибуты в Delphi Win32 поддерживаются на типах, на полях записей и полей, методах, их параметрах и свойствах классов.

Декларации атрибутов не вызывают ошибок из-за обратной совместимости с Delphi для .NET.

14
ответ дан 1 December 2019 в 19:02
поделиться

Хотя Барри явно ответил на ваш вопрос относительно атрибутов на элементах Enum, я возьму удар по другому предложению. Исходя из вашего примера, вы префиксировали каждый элемент enum с помощью «TOD», как это традиционно в Delphi, потому что элементы Enum являются глобальными по объему (т. Е. Если у вас был идентификатор TODABC в области применения в дополнение к элементам ToDabc Enum, вы могли бы получить некоторые странное поведение).

Начиная с D2007, мы ввели понятие «Scoped Enums», которые, когда включены, требуют, чтобы вы квалифицировали элемент Enum с идентификатором самого Enum. Например:

{$SCOPEDENUMS ON}
type
  TTypeOfData = (ABC,DEF,GHI);

потребует от вас ссылаться на элемент ABC как TTYPEOFDATA.ABC. Это позволяет использовать не предварительно префиксные идентификаторы элементов Enum и не запускать риск возникновения конфликтов, поскольку элементы «выделены» на перечисление. Любой enum объявлен, когда {$ Scopedenums} включен, будет вести себя таким образом.

Учитывая, что теперь вы можете безопасно использовать RTTI, чтобы получить фактические имена элементов Enum в желаемом формате.

18
ответ дан 1 December 2019 в 19:02
поделиться

Это хороший обзор RTTI в Delphi 2010 в Интернете: http://robstechcorner.blogspot.com/2009/09/so-what-is-rttti-rttti - Acronym - for-run.html

Вы можете получить значения перечисления и обратно по орналалам, используя «старые» функции RTTI в устройстве Typinfo (GetNUMValue, GetEnumname). И заправьте строчные буквы, которые вы получаете тот же результат, что и выше, но она не такой гибкий.

3
ответ дан 1 December 2019 в 19:02
поделиться

Для тех, кто перерезан в практическом решении этой проблемы, я решил ее таким образом:

type
  TTypeOfData = (todABC, todDEF, todGHI);

  TMySerializableClass = class
  private
    FType: TTypeOfData;
  public
    property &Type: TTypeOfData read FType write FType;
    class function TypeOfDataAsString(&Type: TTypeOfData): String;
  end;

implementation

class function TMySerializableClass.TypeOfDataAsString(&Type: TTypeOfData): String;
const
  TYPE_STRING: array[TypeOfDataAsString] of String = ('ABC', 'DEF', 'GHI);
begin
  Result := TYPE_STRING[&Type];
end;

, а затем в коде сериализации, я использую RTTI для поиска традиционной функции класса. Названный ASSTRING и называть его с недвижимостью TVALUE:

procedure Serialize(const V: TValue);
var
  N: String;
  T: TRttiType;
  F: TRttiField;
  M: TRttiMethod;
  R: TValue;
 begin
   case V.TypeInfo^.Kind of
   tkEnumeration:
   begin
     T := Ctx.GetType(TypeInfo(TMySerializableClass));
     N := V.TypeInfo.Name + 'AsString';
     if N[1] = 'T' then
       Delete(N, 1, 1);
     M := T.GetMethod(N);
     if (M <> nil) and M.IsClassMethod and (M.MethodKind = mkClassFunction) and (M.ReturnType.TypeKind = tkUString) then
     begin
       R := M.Invoke(TTicket, [V]);
       // serialize R.AsString
     end;
   end;
   ...
 end;
1
ответ дан 1 December 2019 в 19:02
поделиться

Хорошо, я думаю, что нашел лучшее решение. Я объявляю новый тип атрибута, например:

TEnumAttribute = class (TCustomAttribute)
  private 
    FCaption : string;
  public
    constructor Create (const Caption : string);
    property Caption : string read FCaption write FCaption;
end;

Теперь я добавляю атрибуты в свое перечисление:

[TEnumAttribute ('Normal')]
[TEnumAttribute ('High')]
TExampleEnum = (eeNormal,eeHigh);

Теперь легко получить доступ к атрибутам по порядковому номеру:

RttiType := RttiContext.FindType ('ExampleUnit.TExampleEnum');
RttiAttributes := Rttitype.GetAttributes;
Test := TEnumAttributes(RttiAttributes[index]).Caption;
3
ответ дан 1 December 2019 в 19:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: