7

値を保持し、値が変更されるたびにイベントを発生させ、保持している型との間で暗黙的に変換するクラスを作成しようとしています。

私の目標は、クラスのObservableプロパティを作成し、別のクラス(WPFコントロールを含む)が通常の文字列であるかのように読み書きできるようにすることです。他のクラスは、Observableとしての参照を維持したり、新しいイベントを作成せずに独自のプロパティとして公開したりすることもできます。

これが私がこれまでに持っているものです:

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

問題は、「=」演算子がオーバーロードできないと文句を言っていることです。それはあらゆる種類の奇妙な行動につながる可能性があるので、それは理にかなっていると思います。私が目指していることを達成する別の方法はありますか?

編集:これが私がこれを実装することに決めた方法です。もっと良い提案があれば教えてください:)

このケースは、Observableを保持するプロパティによって実際に処理される必要があることに気付きました。これが私がやりたいことの例です:

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

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

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

もちろん、Propertyは2回定義されているため、コンパイルされません。これは、(多くの人が示唆しているように)暗黙の変換を別の方法で定義することを考えているややハックな回避策です。

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

それを使用してプロパティのセッターを呼び出します。

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

3 に答える 3

4

implicit演算子をオーバーロードできます。

public static operator implicit string(YourObject object)

と逆に行く

public static operator implicit YourObject(string s)

ただし、これは非常に危険であることに注意してください。それは、クラスの消費者があなたが思いもよらなかったいくつかのことをすることにつながる可能性があります。そして意味をなさないいくつかの振る舞い。

于 2012-12-21T19:31:24.263 に答える
4

C#のオーバーロード可能な演算子を見ると、次のことがわかります。

代入演算子はオーバーロードできませんが、たとえば+ =は、オーバーロードできる+を使用して評価されます。

ただし、を作成することはできます。これにより、からをimplicit operator Observable<T>(T value)暗黙的に変換できます。TObservable<T>

そうは言っても、私はこれをお勧めしません。割り当てを明示的にします。これは、呼び出されるたびに新しいものを作成する必要があり、各割り当てによって新しいオブジェクトインスタンスが作成されるため、イベントハンドラーで問題が発生するためです。 Observable<T>

于 2012-12-21T19:36:45.703 に答える
3

これらの行に沿って、別の暗黙の変換を追加します。

public static implicit operator Observable<T>(T value)
{
    return new Observable<T>{Value = value};
}
于 2012-12-21T19:33:43.833 に答える