2015-03-28 16 views
5

Có thể và cách tạo và đính kèm thuộc tính tùy chỉnh vào trường trong thời gian chạy không?Cách tạo và đính kèm thuộc tính tùy chỉnh vào trường tại thời gian chạy ở Delphi

uses 
    System.SysUtils, 
    System.Classes, 
    System.Rtti; 

type 
    MyAttribute = class(TCustomAttribute) 
    private 
    fCaption: string; 
    public 
    constructor Create(const aCaption: string); 
    property Caption: string read fCaption write fCaption; 
    end; 

    TFoo = class(TPersistent) 
    public 
    [MyAttribute('Title')] 
    Bar: string; 
    Other: string; 
    end; 

constructor MyAttribute.Create(const aCaption: string); 
begin 
    fCaption := aCaption; 
end; 

procedure CreateAttributes(Typ: TRttiType); 
var 
    Field: TRttiField; 
    MyAttr: MyAttribute; 
begin 
    for Field in Typ.GetFields do 
    begin 
     if Length(Field.GetAttributes) = 0 then 
     begin 
      MyAttr := MyAttribute.Create('Empty'); 
      // how to attach created attribute to Field ??? 
     end; 
    end; 
end; 

var 
    Context: TRttiContext; 
    Typ: TRttiType; 
    Field: TRttiField; 
    Attr: TCustomAttribute; 

begin 
    Context := TRttiContext.Create; 
    Typ := Context.GetType(TFoo); 

    CreateAttributes(Typ); 

    for Field in Typ.GetFields do 
    for Attr in Field.GetAttributes do 
     if Attr is MyAttribute then 
     writeln(Field.Name + ' ' + MyAttribute(Attr).Caption); 
    readln; 
    Context.Free; 
end. 

Chạy trên mã sản xuất đầu ra:

Bar Title 

Tôi muốn tiêm MyAttribute với giá trị Empty đến lĩnh vực mà không có nó trong thời gian chạy sản xuất sau đầu ra:

Bar Title 
Other Empty 

Trả lời

2

Khung công tác không cung cấp cơ chế để gắn các thuộc tính vào thời gian chạy. Bất kỳ nỗ lực để làm như vậy sẽ liên quan đến hack khung.

+0

Tôi mặc dù điều này có thể là như vậy. Điều đó chỉ chứng minh rằng các thuộc tính không phù hợp hơn với việc tuần tự hóa so với chỉ thị được công bố. –

+0

@Dalija tại sao các tùy chọn tuần tự hóa khác nhau ở thời gian chạy –

+0

Một lý do cho việc này là thay đổi tuần tự hóa các lớp ngoài tầm kiểm soát của bạn, như trong [JSON serialization without garbage] (http://stackoverflow.com/questions/29276304/how-to-serialize -an-tlistt-to-json-without-garbage) –

0

Thuộc tính là phép thuật thời gian biên dịch. Trong thời gian chạy bạn không cần những thứ như vậy. Chỉ cần tạo từ điển của riêng nơi mà kiểu và thành viên (thành viên có thể được đặt làm chuỗi) là khóa, và danh sách các thuộc tính là giá trị. Và, khi bạn cần phải kiểm tra các thuộc tính làm điều đó bằng hai cách - phổ biến và trong từ điển của bạn.

+0

Cảm ơn, nhưng điều đó không giải quyết được vấn đề khi bạn có lớp ngoài tầm kiểm soát của bạn (bạn không thể thay đổi nó trong thời gian biên dịch) và bạn phải thực hiện hoạt động dựa trên thuộc tính (một lần nữa ngoài tầm kiểm soát của bạn) khi nó hoạt động. Nhìn vào [serialization JSON không có rác] (http://stackoverflow.com/questions/29276304/how-to-serialize-an-tlistt-to-json-without-garbage) để hiểu rõ hơn những gì tôi đang nói đến. –

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