Delphi 2010 RTTI : Explore Enumerations

后端 未结 6 1920
挽巷
挽巷 2021-02-05 16:04

Considering such an enumeration :

type
  TTypeOfData = (
    [XmlName(\'ABC\')] todABC,
    [XmlName(\'DEF\')] todDEF,  
    [XmlName(\'GHI\')] todGHI
  );
         


        
6条回答
  •  夕颜
    夕颜 (楼主)
    2021-02-05 16:14

    For those who are interrested in a practical solution to that problem, I solved it that way :

    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;
    

    And later, in the serialization code, I use RTTI to look for a class function conventionnaly named AsString and call it with the property 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;
    

提交回复
热议问题