2011-10-19 51 views
2

如果我有一個TList,其中有許多不同記錄類型的指針,我如何訪問TList中不同記錄的值?如何通過Delphi XE中的指針獲取記錄的類型信息?

有什麼辦法可以獲得那些引用記錄的記錄類型或類型信息嗎?

我目前使用Delphi XE。

+0

我對RTTI一無所知,但我不認爲指向記錄的指針攜帶着類型信息。我錯了嗎? –

+0

試試這個PRecord(List [i])^。member其中PRecord是^ Yourdefinedrecord ...我真的不明白這個問題... – opc0de

+1

@ opc0de我認爲這個問題是關於你不知道什麼類型的列表在列表中。否則,它與您的評論一樣微不足道。 –

回答

6

您的不同記錄類型需要共同的標題。然後,您可以首先將列表項指針轉​​換爲該頭類型,以確定要將哪個記錄類型轉換爲下一個。例如:

type 
    TRecType = (recA, recB, recC); 

    PRecHeader = ^TRecHeader; 
    TRecHeader = record 
    RecType: TRecType; 
    ... 
    end; 

    PRecordA = ^TRecordA; 
    TRecordA = record 
    Header: TRecHeader; 
    IntValue: Integer; 
    end; 

    PRecordB = ^TRecordB; 
    TRecordB = record 
    Header: TRecHeader; 
    StrValue: String; 
    end; 

    PRecordC = ^TRecordC; 
    TRecordC = record 
    Header: TRecHeader; 
    DblValue: Double; 
    end; 

var 
    PRec: Pointer; 
begin 
    PRec := List[Index]; 
    case PRecHeader(PRec)^.RecType of 
    recA: use PRecordA(PRec)^.IntValue as needed ... 
    recB: use PRecordB(PRec)^.StrValue as needed ... 
    recC: use PRecordC(PRec)^.DblValue as needed ... 
    end; 
end; 
+1

只是使用變體記錄而不是重新實現它會容易得多。 –

+0

即使變體記錄也需要變量區域之外的頭部值來知道要訪問變體數據的哪個部分。 –

+0

是的,但語法更清晰。當然,如果您使用託管類型,如字符串,那麼您不能使用變體記錄! –

3

你真的不能這樣做。與德爾福對象不同,記錄周圍沒有任何RTTI。如果你混合了大量不同類型的數據,並希望能夠找到它們在運行時的數據類型,最好的辦法是簡單地使用對象,這些對象繼承了TObject.ClassType和一些其他的例程使這個任務變得簡單。

如果您確實需要使用記錄,無論出於何種原因,您都必須使用不會更改的自定義標記開始記錄。我正要描述這個系統,但是看起來雷米打敗了我。但是,這帶來了足夠的開銷,再次,你可能只是使用對象,因爲一旦你走得很遠,這條路就基本上重新實現了很多TObject

1

我強烈建議使用Contnrs單位的TObjectList對象。 (它是否仍然存在於Delphi XE中?)這是基於TList,但爲您提供TObject引用而不是指針。這是一個細微的差異,但允許您直接在列表項上使用isas運算符。

+2

'TObjectList'在XE中仍然存在,但對記錄指針沒有幫助。 –

+0

@TOndrej我相信這個建議是擺脫不攜帶類型信息的記錄。 –

1

如何使用帶有{$ M +}對象的pascal樣式?這將消除TObject的開銷

{$M+} 

TRecordA = object 
end; 

TRecordB = object 
end; 

{$M-} 
+2

這裏可能有一個很好的答案,但它需要一些闡述 –

相關問題