创建一个Observable <t>类:overloading = operator?</t>

时间:2012-12-21 19:20:07

标签: c# wpf overloading observable

我正在尝试创建一个包含值的类,每当值发生变化时都会引发一个事件,并且会隐式转换为它所持有的类型。

我的目标是我应该能够创建一个类的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定义了两次。这是一个有点hackish的解决方法,我正在考虑以另一种方式定义隐式转换(正如你们许多人所建议的那样):

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

并使用它来调用属性的setter:

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

3 个答案:

答案 0 :(得分:4)

您可以重载implicit运算符。

public static operator implicit string(YourObject object)

并走另一条路

public static operator implicit YourObject(string s)

请注意,这非常很危险。它可以导致班上的消费者做一些你从未想过的事情;以及一些没有意义的行为。

答案 1 :(得分:4)

如果查看Overloadable Operators in C#,您会看到:

  

分配运算符不能重载,但是+ =,例如,使用+来计算,可以重载。

但是,您可以设置implicit operator Observable<T>(T value),这样您就可以隐式地从T转换为Observable<T>

话虽如此,我不会推荐这个。我会明确地赋值,因为这需要在每次调用时创建一个 new Observable<T>,这将导致事件处理程序出现问题,因为每个赋值都会创建一个新的对象实例。

答案 2 :(得分:3)

在这些行中添加另一个隐式转换:

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