2009-12-05 20 views
5

C# - .net 3.5Phương thức thực hiện bất kỳ lúc nào một thuộc tính lớp được truy cập (nhận hoặc đặt)?

Tôi có một nhóm gia đình kế thừa từ cùng một lớp cơ sở. Tôi muốn một phương thức trong lớp cơ sở được gọi bất kỳ lúc nào một thuộc tính trong một lớp bị loại bỏ được truy cập (nhận hoặc thiết lập). Tuy nhiên, tôi không muốn viết mã trong mỗi và mọi thuộc tính để gọi lớp cơ sở ... thay vào đó, tôi hy vọng có một cách khai báo để "chìm" hoạt động này vào lớp cơ sở.

Thêm một số gia vị vào yêu cầu, tôi cần xác định tên của thuộc tính đã được truy cập, giá trị thuộc tính và loại của thuộc tính.

Tôi tưởng tượng giải pháp sẽ là sự kết hợp thông minh của đại biểu, generics và phản ánh. Tôi có thể hình dung việc tạo ra một số kiểu phân bổ ủy nhiệm trong thời gian chạy, nhưng việc lặp lại qua MemberInfo trong hàm tạo sẽ tác động đến hiệu năng nhiều hơn tôi muốn. Một lần nữa, tôi hy vọng có một cách "khai báo" trực tiếp hơn để làm điều này.

Bất kỳ ý tưởng nào được đánh giá cao nhất!

Trả lời

2

Tôi không tin rằng điều này là có thể làm khai báo, tôi chưa bao giờ thấy nó được thực hiện theo cách đó. Tuy nhiên, những gì bạn có thể làm là thực hiện giao diện INotifyPropertyChanged trên lớp cơ sở của bạn, và có việc thực hiện giao diện trong lớp cơ sở. Một cái gì đó như thế này:

public class A : INotifyPropertyChanged 
{ 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 

    protected virtual void RaiseOnPropertyChanged(object sender, string propertyName) 
    { 
     if (this.PropertyChanged != null) 
      PropertyChanged(sender, new PropertyChangedEventArgs(propertyName); 
    } 

    public A() 
    { 
     this.PropertyChanged += new PropertyChangedEventHandler(A_PropertyChanged); 
    } 

    void A_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     //centralised code here that deals with the changed property 
    } 
} 


public class B : A 
{ 
    public string MyProperty 
    { 
     get { return _myProperty; } 
     set 
     { 
      _myProperty = value; 
      RaiseOnPropertyChanged(this, "MyProperty"); 
     } 
    } 

    public string _myProperty = null; 
} 
+0

Tôi cũng nên chỉ ra rằng trong khi INotifyPropertyChanged cho phép bạn chuyển tên thuộc tính, nó không mất một nhà khoa học tên lửa để đưa khái niệm thêm một bước nữa và viết phiên bản giao diện của riêng bạn. thông qua. Mặc dù những gì bạn đang đề xuất, trong khi nó có thể âm thanh thông minh trong lý thuyết, sẽ thêm rất nhiều chi phí cho ứng dụng của bạn, và bạn sẽ phải xem xét việc chuyển đổi biên dịch có điều kiện trong mã của bạn. – slugster

4

Bạn không thể tự động thực hiện, nhưng bạn có thể nhận được 95% miễn phí. Đây là trường hợp điển hình cho lập trình hướng đối tượng. Hãy xem PostSharp, có lớp OnFieldAccessAspect. Dưới đây là cách bạn có thể giải quyết vấn đề của mình:

[Serializable] 
public class FieldLogger : OnFieldAccessAspect { 
    public override void OnGetValue(FieldAccessEventArgs eventArgs) { 
     Console.WriteLine(eventArgs.InstanceTag); 
     Console.WriteLine("got value!"); 
     base.OnGetValue(eventArgs); 
    } 

    public override void OnSetValue(FieldAccessEventArgs eventArgs) { 
     int i = (int?)eventArgs.InstanceTag ?? 0; 
     eventArgs.InstanceTag = i + 1; 
     Console.WriteLine("value set!"); 
     base.OnSetValue(eventArgs); 
    } 

    public override InstanceTagRequest GetInstanceTagRequest() { 
     return new InstanceTagRequest("logger", new Guid("4f8a4963-82bf-4d32-8775-42cc3cd119bd"), false); 
    } 
} 

Bây giờ, mọi thứ kế thừa từ FieldLogger sẽ có cùng hành vi. Mau!

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