2012-12-21 15 views
7

Ich versuche, eine Klasse zu erstellen, die einen Wert enthält, wird ein Ereignis auslösen, wann immer sich der Wert ändert, und wird implizit in und von dem Typ konvertieren, der es enthält.Observable erstellen <T> Klasse: overloading = operator?

Mein Ziel ist es, dass ich in der Lage sein sollte, eine Observable-Eigenschaft einer Klasse zu erstellen und eine andere Klasse (einschließlich WPF-Steuerelemente) in der Lage zu lesen und zu schreiben, als ob es eine normale Zeichenfolge wäre. Andere Klassen können einen Verweis darauf als Observable beibehalten oder sie sogar als eigene Eigenschaft verfügbar machen, ohne dass neue Ereignisse erstellt werden müssen. Hier

ist das, was ich bisher:

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; 
     } 
    } 
} 

Das Problem ist, dass der Operator „=“ beschwert sich, dass er nicht überlastet werden kann. Ich denke, das macht Sinn, da es zu allen möglichen seltsamen Verhaltensweisen führen kann. Gibt es einen anderen Weg, um zu erreichen, wofür ich hingehe?

EDIT: Hier ist, wie ich mich entschieden habe, dies zu implementieren. Lassen Sie mich wissen, wenn es bessere Vorschläge gibt :)

Ich erkannte, dass dieser Fall wirklich von der Eigenschaft behandelt werden sollte, die das Observable hält. Hier ist ein Beispiel dafür, was Ich mag zu tun wäre:

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

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

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

Natürlich, die nicht kompiliert, da Property zweimal definiert ist. Hier ist die etwas hackish Abhilfe, die ich denke, eine implizite Konvertierung in die andere Richtung zu definieren (wie viele von Ihnen vorgeschlagen haben):

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

und die Verwendung dieser der Unterkunft Setter zu nennen:

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

Antwort

4

Sie können den Operator implicit überladen.

public static operator implicit string(YourObject object) 

und in die andere Richtung

public static operator implicit YourObject(string s) 

Beachten Sie aber zu gehen, ist dies sehr gefährlich. Es kann dazu führen, dass die Konsumenten der Klasse einige Dinge tun, an die Sie nie gedacht haben; und etwas Verhalten, das keinen Sinn ergibt.

+0

Ich dachte darüber nach, aber hier ist das Problem. Nehmen wir an, ich mache folgendes: [Observable A = neue Observable (); Beobachtbar B = A; A = "hi";] Nun sind A und B nicht mehr synchron, da wir anstelle von A den Wert von A durch ein neues Observable-Objekt ersetzt haben. – hypehuman

+0

Eigentlich habe ich beschlossen, dass das in der Tat für mich funktioniert. Ich werde meine Frage bearbeiten, um zu erklären, wie. – hypehuman

3

weiteren hinzufügen implizite Konvertierung, in dieser Richtung:

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

Wenn man sich die Overloadable Operators in C# suchen, werden Sie sehen, dass:

Zuweisungsoperatoren können nicht überlastet werden, sondern + =, für Beispiel, wird mit + ausgewertet, was überladen werden kann.

Sie können eine implicit operator Observable<T>(T value) machen, aber, die Sie implizit T-Observable<T> zu konvertieren erlauben würde.

Das gesagt, ich würde das nicht empfehlen.Ich würde die Zuordnung explizit machen, da dies bei jedem Aufruf ein neuesObservable<T> erfordern würde, was zu Problemen mit Ihren Event-Handlern führen würde, da jede Zuweisung eine neue Objektinstanz erzeugt.