2012-12-21 42 views
7

Tôi đang cố gắng tạo một lớp chứa một giá trị, sẽ tăng một sự kiện bất cứ khi nào giá trị thay đổi và sẽ chuyển đổi hoàn toàn đến và từ loại nó giữ.Tạo một lớp học quan sát <T>: quá tải = toán tử?

Mục tiêu của tôi là tôi có thể tạo thuộc tính có thể quan sát của một lớp và có một lớp khác (bao gồm cả điều khiển WPF) có thể đọc và ghi vào nó như thể đó là chuỗi thông thường. Các lớp khác có thể duy trì một tham chiếu đến nó như là một Observable, hoặc thậm chí phơi bày nó như là thuộc tính riêng của nó mà không cần phải tạo các sự kiện mới.

Dưới đây là những gì tôi có cho đến nay:

using System; 
using System.ComponentModel; 

namespace SATS.Utilities 
{ 
    public class Observable<T> 
    { 
     private T mValue; 

     public event EventHandler ValueChanged; 
     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyValueChanged() 
     { 
      if (ValueChanged != null) 
      { 
       ValueChanged(this, new EventArgs()); 
      } 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("Value")); 
      } 
     } 

     public T Value 
     { 
      get 
      { 
       return mValue; 
      } 
      set 
      { 
       SetValueSilently(value); 
       NotifyValueChanged(); 
      } 
     } 

     public void SetValueSilently(T value) 
     { 
      mValue = value; 
     } 

     public static implicit operator T(Observable<T> observable) 
     { 
      return observable.Value; 
     } 

     public static T operator =(Observable<T> observable, T value) // Doesn't compile! 
     { 
      observable.Value = value; 
      return value; 
     } 
    } 
} 

Vấn đề là các "=" nhà điều hành đang phàn nàn rằng nó không thể bị quá tải. Tôi đoán điều đó có ý nghĩa, vì nó có thể dẫn đến tất cả các loại hành vi kỳ lạ. Có cách nào khác để đạt được điều tôi sẽ làm không?

EDIT: Đây là cách tôi đã quyết định triển khai tính năng này. Hãy cho tôi biết nếu có bất kỳ gợi ý nào tốt hơn :)

Tôi nhận ra rằng trường hợp này thực sự phải được xử lý bởi thuộc tính chứa Đài quan sát. Dưới đây là một ví dụ về những gì tôi muốn làm:

public class A 
{ 
    private readonly Observable<string> _property; 

    public Observable<string> Property 
    { 
     get { return _property; } 
    } 

    public string Property 
    { 
     set { _property.Value = value; } 
    } 
} 

Tất nhiên, điều đó không biên dịch vì tài sản được định nghĩa hai lần. Đây là cách giải quyết phần nào hackish mà tôi đang nghĩ đến việc xác định một chuyển đổi ngầm theo cách khác (như nhiều bạn đã gợi ý):

public static implicit operator Observable<T>(T value) 
{ 
    var result = new Observable<T>(); 
    result.SetValueSilently(value); 
    return result; 
} 

và sử dụng rằng để gọi của tài sản setter:

public Observable<string> Property 
{ 
    get { return _property; } 
    set { _property.Value = value.Value; } 
} 

Trả lời

4

Bạn có thể quá tải toán tử implicit.

public static operator implicit string(YourObject object) 

và đi theo con đường khác

public static operator implicit YourObject(string s) 

Hãy nhận biết, tuy nhiên, đây là rất nguy hiểm. Nó có thể dẫn đến người tiêu dùng của lớp học để làm một số điều bạn không bao giờ nghĩ đến; và một số hành vi không có ý nghĩa.

+0

Tôi đã nghĩ về điều đó, nhưng đây là vấn đề. Hãy nói rằng tôi làm như sau: [Quan sát A = new Observable (); Có thể quan sát B = A; A = "hi";] Bây giờ, A và B không đồng bộ vì thay vì đặt giá trị của A, chúng tôi đã thay thế nó bằng một đối tượng Quan sát mới. – hypehuman

+0

Trên thực tế, tôi đã quyết định rằng điều này thực sự sẽ làm việc cho tôi. Tôi sẽ chỉnh sửa câu hỏi của tôi để giải thích như thế nào. – hypehuman

3

Thêm một chuyển đổi ngầm, cùng những dòng này:

public static implicit operator Observable<T>(T value) 
{ 
    return new Observable<T>{Value = value}; 
} 
4

Nếu bạn nhìn vào Overloadable Operators in C#, bạn sẽ thấy rằng:

khai thác Chuyển nhượng không thể bị quá tải, nhưng + =, cho ví dụ, được đánh giá bằng cách sử dụng +, có thể bị quá tải.

Bạn có thể thực hiện một implicit operator Observable<T>(T value), tuy nhiên, điều này sẽ cho phép bạn chuyển đổi ngầm T-Observable<T>.

Điều đó đang được nói, tôi sẽ không đề xuất điều này.Tôi sẽ thực hiện nhiệm vụ rõ ràng, vì điều này sẽ yêu cầu tạo mớiObservable<T> mỗi khi được gọi, điều này sẽ gây ra sự cố với trình xử lý sự kiện của bạn, vì mỗi nhiệm vụ sẽ tạo một đối tượng mới.

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