我正在尝试创建一个包含一个值的类,每当值更改时都会引发一个事件,并将隐式转换为它所持有的类型。
我的目标是我应该能够创建一个类的 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; }
}