【问题标题】:Creating an Observable<T> class: overloading = operator?创建 Observable<T> 类:重载 = 运算符?
【发布时间】:2012-12-09 09:01:06
【问题描述】:

我正在尝试创建一个包含值的类,每当值更改时将引发一个事件,并将隐式转换为它所持有的类型。

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

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

【问题讨论】:

    标签: c# wpf overloading observable


    【解决方案1】:

    您可以重载implicit 运算符。

    public static operator implicit string(YourObject object)
    

    走另一条路

    public static operator implicit YourObject(string s)
    

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

    【讨论】:

    • 我想过,但问题就在这里。假设我执行以下操作: [Observable A = new Observable();可观察 B = A; A = "hi";] 现在,A 和 B 不同步了,因为我们没有设置 A 的值,而是将其替换为一个新的 Observable 对象。
    • 实际上,我已经决定这确实对我有用。我将编辑我的问题以解释如何。
    【解决方案2】:

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

    赋值运算符不能重载,但 +=,例如,使用 + 计算,可以重载。

    您可以创建一个implicit operator Observable&lt;T&gt;(T value),但是,这将允许您从T 隐式转换为Observable&lt;T&gt;

    话虽如此,我不会推荐这个。我会明确分配,因为这需要在每次调用它时创建一个 new Observable&lt;T&gt;,这会导致您的事件处理程序出现问题,因为每个分配都会创建一个新的对象实例.

    【讨论】:

      【解决方案3】:

      添加另一个隐式转换,如下所示:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 2019-10-16
        相关资源
        最近更新 更多