2011-03-25 3 views
4

RTTI를 사용하여 열거 형 필드 값을 설정하는 방법은 무엇입니까?열거 형의 Delphi RTTI SetValue

e.e.

type 
    TCPIFileStatus= (fsUnknown, fsProcessed); 
    TTest = class 
    FStatus: TCPIFileStatus; 
    end; 
     ... 
    var 
    Data: TTest; 
    Ctx: TRttiContext; 
    Status : TCPIFileStatus; 
    begin 
    Data := TTest.Create; 
    Status := fsProcessed; 
    Ctx.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, Status); 
    end; 

"잘못된 클래스 유형 변환"이 표시됩니다.
NB : 디자인 타임에 객체 유형이나 필드 이름을 항상 알지 못하기 때문에 RTTI를 사용해야합니다.

답변

6

당신은 통과해야이 코드를 사용해보십시오 TValueSetValue 방법 A :

{$APPTYPE CONSOLE} 
uses 
    Rtti, 
    SysUtils; 


type 
    TCPIFileStatus= (fsUnknown, fsProcessed); 
    TTest = class 
    FStatus: TCPIFileStatus; 
    end; 

    var 
    Data : TTest; 
    Ctx : TRttiContext; 
    Status : TCPIFileStatus; 
    v  : TValue; 
begin 
    try 
    Data := TTest.Create; 
    try 
     Status := fsProcessed; 
     v:= v.From(status); 
     Ctx.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, v); 

     // do your stuff 
    finally 
     Data.Free; 
    end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

감사합니다. FromVariant와 FromOrdinal을 살펴보고 From 메서드를 놓쳤습니다. –

0

사용 TValue.From SetValue는 방법으로 전달하는 호환 TValue 값을 구하는 일반적인 방법 ...

type 
    TCPIFileStatus= (fsUnknown, fsProcessed); 
    TTest = class 
    FStatus: TCPIFileStatus; 
    end; 

procedure TForm2.Button1Click(Sender: TObject); 
var 
    Data: TTest; 
    Ctx: TRttiContext; 
    Status : TCPIFileStatus; 
    AValue: TValue; 
begin 
    Data := TTest.Create; 
    try 
    Status := fsProcessed; 
    Ctx.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, TValue.From(Status)); 
    Assert(Data.FStatus = Status, 'Something wrong on assigning status trough RTTI!'); 
    finally 
    Data.Free; 
    end; 
end; 
1

이 문제에 대한 또 다른 해결책, 당신이 정확한 열거가 입력 모르는 경우 : 음 ... 더 나은 코드, 단어에서 얻을 어렵다 함수가 아니라 TypeInfo가 아니라 TValue의 Make 프로 시저를 사용하는 것입니다. 여기

procedure Make(AValue: NativeInt; ATypeInfo: PTypeInfo; out Result: TValue); overload; static; 

은 (는 XML 설정 파서에서) 예입니다 이 나중에 TRTTIField/TRTTIProperty.SetValue()이 당신을 도와줍니다

function EnumNameToTValue(Name: string; EnumType: PTypeInfo): TValue; 
var 
    V: integer; 

begin 
    V:= GetEnumValue(EnumType, Name); 
    TValue.Make(V, EnumType, Result); 
end; 

희망에 사용됩니다.