2011-12-30 44 views
6

Tôi muốn liệt kê tất cả các thuộc tính: riêng tư, được bảo vệ, công khai, v.v. Tôi muốn sử dụng các tiện ích được xây dựng và không sử dụng bất kỳ mã của bên thứ ba nào.Làm cách nào để liệt kê tất cả các thuộc tính trong đối tượng và nhận giá trị của chúng?

+0

Bạn đang làm việc với phiên bản Delphi nào? RTTI nâng cao chỉ khả dụng kể từ Delphi 2010. Phiên bản cũ hơn sẽ không thể đạt được điều này: chỉ các thuộc tính được xuất bản mới có thể được liệt kê. –

+1

Bạn đang hỏi về việc nhận các giá trị của tất cả các thuộc tính. RTTI mới, có sẵn trong Delphi XE2, có thể làm điều này. Liên kết tôi đăng dưới dạng trùng lặp là một số tham chiếu về việc sử dụng RTTI, nói chung. Không có dấu hiệu của phiên bản Delphi bạn đang sử dụng. Vì bạn đã chỉnh sửa câu hỏi của mình, tôi đã xóa bản sao của mình. –

+1

@DavidHeffernan, Cảm ơn bạn đã sửa đổi câu hỏi của tôi một cách độc đáo. – VibeeshanRC

Trả lời

5

Dùng Extended RTTI như thế này (khi tôi kiểm tra mã trong XE Tôi có ngoại lệ về sở hữu ComObject, vì vậy tôi chèn thử - ngoại trừ khối):

uses RTTI; 
procedure TForm1.Button1Click(Sender: TObject); 
var 
    C: TRttiContext; 
    T: TRttiType; 
    F: TRttiField; 
    P: TRttiProperty; 

    S: string; 

begin 
    T:= C.GetType(TButton); 
    Memo1.Lines.Add('---- Fields -----'); 
    for F in T.GetFields do begin 
    S:= F.ToString + ' : ' + F.GetValue(Button1).ToString; 
    Memo1.Lines.Add(S); 
    end; 

    Memo1.Lines.Add('---- Properties -----'); 
    for P in T.GetProperties do begin 
    try 
     S:= P.ToString; 
     S:= S + ' : ' + P.GetValue(Button1).ToString; 
     Memo1.Lines.Add(S); 
    except 
     ShowMessage(S); 
    end; 
    end; 
end; 
7

câu trả lời SERG là tốt nhưng nó là tốt hơn để tránh trường hợp ngoại lệ bằng cách bỏ qua một số loại:

uses 
    Rtti, TypInfo; 

procedure TForm4.GetObjectProperties(AObject: TObject; AList: TStrings); 
var 
    ctx: TRttiContext; 
    rType: TRttiType; 
    rProp: TRttiProperty; 
    AValue: TValue; 
    sVal: string; 
const 
    SKIP_PROP_TYPES = [tkUnknown, tkInterface]; 
begin 
    if not Assigned(AObject) and not Assigned(AList) then 
    Exit; 

    ctx := TRttiContext.Create; 
    rType := ctx.GetType(AObject.ClassInfo); 
    for rProp in rType.GetProperties do 
    begin 
    if (rProp.IsReadable) and not (rProp.PropertyType.TypeKind in SKIP_PROP_TYPES) then 
    begin 
     AValue := rProp.GetValue(AObject); 
     if AValue.IsEmpty then 
     begin 
     sVal := 'nil'; 
     end 
     else 
     begin 
     if AValue.Kind in [tkUString, tkString, tkWString, tkChar, tkWChar] then 
      sVal := QuotedStr(AValue.ToString) 
     else 
      sVal := AValue.ToString; 
     end; 

     AList.Add(rProp.Name + '=' + sVal); 
    end; 

    end; 
end; 
2

Dưới đây là một điểm khởi đầu tuyệt vời sử dụng khả năng tiên tiến của phiên bản mới Delphi:

Liên kết sau thay vì nhắm mục tiêu phiên bản đầu tiên (từ D5 trở lên). Dựa trên đơn vị TypInfo.pas, nó có giới hạn nhưng vẫn mang tính hướng dẫn:

Các vấn đề liên quan