2012-10-19 43 views
6

Chúng tôi đang thực hiện rất nhiều việc triển khai INotifyPropertyChanged trong Mô hình Chế độ xem của chúng tôi và thực sự cảm thấy mệt mỏi vì phải kích hoạt các sự kiện đã thay đổi rõ ràng trong mã của chúng tôi vì lý do bất tiện và thẩm mỹ.Thêm phương pháp mở rộng vào Thuộc tính Accessor

Tôi muốn đặt một phần mở rộng trên setter tài sản của chúng tôi, làm cho kết quả nhìn mã như:

public string LazyAccessor 
{ 
    get; 
    set.notify(); 
} 

Có cách nào để làm điều này? Chúng ta có thể tạo ra một cái nếu không?

Trả lời

3

Extension methods chỉ có thể được thêm vào loại. Các getters và setters trên các thuộc tính tự động được chuyển đổi thành các phương thức với các biến sao lưu bởi trình biên dịch, vì vậy không có cách nào để đặt một phương thức mở rộng trên chúng.

2

Có cách nào để thực hiện việc này không?

Không, không có, không giống như bạn đã đăng. Các phương thức tiện ích mở rộng hoạt động trên các loại, chứ không phải là getters hoặc setters.

Chúng ta có thể tạo ra một cái nếu không có?

Điều đó sẽ yêu cầu thay đổi đối với đặc tả C# - không phải là điều có thể xảy ra.

Có các cách tiếp cận khác mà bạn có thể thực hiện để giảm bớt việc này - bằng cách sử dụng một lớp cơ sở với phương pháp sẽ làm cho tấm lò hơi kêu gọi bạn ví dụ.

+0

Một cách tiếp cận thú vị khác. Bạn có thể nhìn vào câu trả lời của tôi và xem nếu đó là khả thi quá? Tôi đánh giá cao ý kiến ​​của bạn như danh tiếng của bạn trước bạn. Có lẽ nó quá nặng? –

0

Họ không đăng nhập vào 4.0, nhưng được đồn đại là được bao gồm trong 5.0.

Tôi đã tìm thấy cách tiếp cận this hữu ích.

4

Khám phá NotifyPropertyWeaver. Điều này sẽ sửa đổi mã của bạn trong quá trình xây dựng để các thuộc tính của bạn triển khai mẫu INotifyPropertyChanged.

Điều này có sẵn dưới dạng Visual Studio Extension

+0

Tôi lấy nó là tiền thân của AOP với những thứ như PostSharp hoặc họ không biết PostSharp tồn tại? –

+0

@ BigM Tôi không thực sự chắc chắn về chi tiết về cách thức hoạt động của chúng. Tôi biết cả hai đều sử dụng IL Dệt, do đó, họ là tương tự như trong khái niệm. Lý do tôi sử dụng NotifyPropertyWeaver là bạn không cần phải lộn xộn mã của bạn với các thuộc tính. – cadrell0

+0

Lý do chính đáng để sử dụng giải pháp đó. PostSharp là *** rất *** chung chung và điều này phù hợp để giải quyết ** một ** điểm đau, nó chắc chắn sẽ ngắn gọn hơn! –

0

Bạn không thể tự làm điều đó trên chính bộ đó. Đó là một hành động. tuy nhiên bạn có thể có thể làm điều này:

public static class extensions() 
{ 
    public static NotifyAccessorSet(this string value) { some code } 
} 

public class SomeClass() 
{ 
    ..... 
    private string mAccessor; 

    public string LazyAccessor{ 
    get { return mAccessor; } 
    set { mAccessor = value; mAccessor.NotifyAccessorSet(); } 
    } 

} 

Đó là hơi ra khỏi đỉnh đầu của tôi và hãy ghi nhớ rằng các phương pháp khuyến nông sẽ được áp dụng cho tất cả các chuỗi loại, do đó bạn có thể muốn thực hiện kiểu trả về của riêng bạn và áp dụng phương pháp mở rộng cho nó. Quay trở lại kiểu đó sau đó từ lazyaccessor.

+0

Tôi không chắc chắn, nhưng tôi nghĩ rằng để cháy NotifyPropertyEvent bạn cần phải biết đối tượng ban đầu (người gửi) và tên thuộc tính ("LazyAccessor" trong mẫu này). Vì vậy, mã của bạn sẽ làm cho nó thậm chí nhiều hơn trò chuyện. – Ondra

+0

Bạn sẽ có đối tượng gốc ... nó sẽ là "giá trị" trong hàm NotifyAccessorSet. Trong mọi trường hợp ... chỉ là một gợi ý. phương pháp này sẽ thực hiện một cuộc gọi chức năng bổ sung, điều này sẽ chỉ cung cấp một cách để thực hiện thông báo trong phương thức thiết lập. – DRobertE

0

bạn có thể mô phỏng hành vi 'giống thuộc tính' mà không cần gọi hướng dẫn sự kiện bằng cách ghi đè toán tử chuyển đổi của cấu trúc chung tùy chỉnh. Sau đây là giải pháp của tôi:

public struct column<TType> 
{ 
    private TType _value; 

    private column(TType value) : this() 
    { 
     _value = value; 
    } 

    private void Set(TType value) 
    { 
     // Implement your custom set-behavior... 
    } 

    private TType Get() 
    { 
     // Implement your custom get-behavior... 
     return _value; 
    } 

    public override string ToString() 
    { 
     return _value.ToString(); 
    } 

    public static implicit operator column<TType>(TType p) 
    { 
     column<TType> column = new column<TType>(p); 
     column.Set(p); 
     return column; 
    } 

    public static implicit operator TType(column<TType> p) 
    { 
     return p.Get(); 
    } 
} 

Tôi tuyên bố cấu trúc với thông số chung để tránh lỗi chuyển đổi. Bạn có thể sử dụng nó như thế này:

public class Test 
{ 
    public column<int> kKey; 

    public column<float> dMoney; 

    public column<string> cValue; 


    public Test() 
    { 
     kKey = 42; 
     dMoney = 3.1415926f; 
     cValue = "May the force be with you!"; 
    } 
} 

... Tôi biết, câu hỏi đã lỗi thời nhưng có thể giúp ai đó trong tương lai.

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