2012-09-21 61 views
2

我可以從類中枚舉常量(const)嗎?使用RTTI從類中獲取常量字段

我已經試過

MyClass = class 
const 
    c1 = 'c1'; 
    c2 = 'c2'; 
    c3 = 'c3'; 
end; 

procedure GetConst(); 
var 
    ctx: TRttiContext; 
    objType: TRttiType; 
    field: trttifield; 
    s: string; 
begin 
    ctx := TRttiContext.Create; 
    objType := ctx.GetType(MyClass.ClassInfo); 
    for field in objType.GetDeclaredFields do 
    s:= field.Name; 
end; 

我想獲得C1,C2,C2。

這可能嗎?

編輯: 我想要做的就是定義一些外部符號某些鍵(CAD程序)

symbol1=class 
    const 
    datafield1='datafield1'; 
    datafield2='datafield2'; 
end; 
symbol2=class 
    const 
    datafield21='datafield21abc'; 
    datafield22='datafield22abc'; 
end 

我不喜歡,因爲我不喜歡單獨declareration使用字段這個和初始化。 我無法使用枚舉,因爲我無法將該值定義爲字符串。

+1

可能不是。編譯時可能沒有更多的常量,而是立即值。還有一點意義分別 –

+0

kkep他們,如果你做了一個枚舉,你可以TypInfo'加上'你'uses'條款,然後使用'GetEnumName'和'GetEnumValue'字符串和序數值之間的轉換。 –

+0

但枚舉值只能是整數的權利?我需要字符串 –

回答

4

你不能通過RTTI得到這些常量。我懷疑你的最佳解決方案是使用屬性來代替。這不僅有實際工作的好處,我認爲這聽起來像是一個更簡單,更簡單的解決方案。

+0

屬性究竟是什麼?他們應該包含什麼? –

+0

每個包含其密鑰的類的屬性。 –

3

如果你使用一個枚舉,您可以使用TypInfo在代碼轉換字符串到枚舉值,和枚舉值到字符串:

type 
    TDataFieldName = (datafield1, datafield2, datafield3); 

uses TypInfo; 

var df: TDataFieldName; 
begin 
    df := TDataFieldName(GetEnumValue(TypeInfo(TDataFieldName), 'datafield1')); 

    ShowMessage(GetEnumName(TypeInfo(TDataFieldName), Ord(df))); 

    case df of 
    datafield1:; 
    datafield2:; 
    datafield3:; 
    end; 
end; 

(從我頭上敲擊 - 沒有測試這...)

通過這種方式,CAD程序可以將字符串傳遞到您的Delphi應用程序,你可以把它們翻譯成枚舉,也可以枚舉轉換爲字符串傳遞給CAD程序。執行case聲明也很容易,其中原始值是一個字符串,並轉換爲枚舉。由於Delphi不支持string個案陳述,所以這已經非常方便了。

+0

在這種情況下,RTTI是否會在類中聲明var字段帶來很多開銷?是否有一個通用的基類型枚舉,所以我可以做一個通用的方法來處理符號1和符號2 –

+0

我從來沒有分析RTTI開銷 - 但我通常使用這個,所以我可以使用'case'語句轉換字符串到一個枚舉(參見上面的編輯)。我從來沒有任何性能問題。 –

0

我決定在我的班級使用的字段。由於我不想複製領域的聲明和初始化,我使用rtti初始化字段的值字段。

的好處是:在運行時沒有RTTI開銷。 rtti僅在應用程序啓動過程中執行。另外我得到使用繼承,這對我的項目非常有用。

+0

很好。很高興你有一個解決方案。但是,這不是你問的問題的答案。請記住,您問是否可以使用RTTI來獲取類常量。 –

+0

關於問題的解決方案而不是您對問題的回答,您是否考慮過方法調用來檢索這些字段名稱?如果你有一個共同的祖先,這可能是一個虛擬類方法。否則,它可能需要成爲一個接口。 –

+0

我可能沒有清楚地傳達這些信息,但我需要能夠枚舉key並隨時提供諸如key1.field1之類的密鑰。我可以添加一個方法來使用rtti,但看起來像一個細節。 –