如何使用onChange事件扩展类型

本文关键字:扩展 类型 事件 onChange 何使用 | 更新日期: 2023-09-27 17:49:18

我特别想添加一个onChange事件到字符串类,我怎么能做到这一点?

我有一个字符串字典作为我的一个类的成员。这些字符串中的一个或多个可能具有需要在其更改时调用的函数。此函数由使用类的代码定义。

如果可能的话,最简单的方法似乎是向string添加一个事件处理程序,或者创建一个继承string的新类,并让我的字典保存它们。我该怎么做呢?

更新:

我的字典目前是字符串,但我可以改变它为int或动态没有太多的麻烦。

如何使用onChange事件扩展类型

没有必要将这样的事件添加到字符串中,因为字符串是不可变的。你不能改变它们的内容,只能用你想要的内容创建新的字符串。

现在,您可以修改字符串变量通过改变它指向的字符串值。例如,在以下代码中:

string s = "Hello";
s = s + " there";

将两个字符串"Hello"answers"there"连接起来,生成一个新字符串。然后将变量s更新为指向新字符串。如果string类有Changed事件,并且您侦听s上的更改,如下所示:

string s = "Hello";
s.Changed += ((sender, args) => MessageBox.Show("changed!"));
s = s + " there";

事件永远不会触发,消息也永远不会被看到。这是因为,在赋值s = s + " there"中,您注册事件处理程序的字符串将被丢弃。您注册了字符串"Hello"的更改,该字符串被新字符串"Hello there"所取代。

你的字典也有类似的情况。考虑下面的代码,同样使用虚构的Changed事件:

Dictionary<string, string> dict = new Dictionary<string, string>();
dict["foo"] = "bar";
dict["foo"].Changed += ((sender, args) => MessageBox.Show("changed!"));
dict["foo"] = "the replacement string";

这里,Changed事件永远不会触发,消息永远不会显示,因为您永远不会改变字符串"bar"的值。相反,您正在用另一个字符串"替换字符串"替换字符串"bar"。字符串"bar"被丢弃。

可以做的,正如其他人所建议的,是定义一个新的类,其中对数据结构的访问必须通过您自己的gatekeeper方法,您可以识别修改内部数据结构的情况并相应地触发Changed事件。

字符串是密封的。你不能从他们那里继承。在任何情况下,它们都是不可变的,永远不能被改变。您可以做的最接近的事情是使用INotifyPropertyChanged订阅对象中的属性更改。在本例中,我创建了一个侦听器,当Foo中的一个属性值发生变化时,该侦听器将得到更新。

void Main() {
    var f = new Foo();
    f.PropertyChanged += (sender, e) => 
        Console.WriteLine ("Changed: {0}", e.PropertyName);
    f.Name = "asdf";
    f.Size = 123;
}
class Foo
    : System.ComponentModel.INotifyPropertyChanged
{
    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    private string _Name;
    public string Name {
        get {
            return this._Name;
        }
        set {
            if (this.PropertyChanged != null) {
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Name"));
            }
            this._Name = value;
        }
    }
    private int _Size;
    public int Size {
        get {
            return this._Size;
        }
        set {
            if (this.PropertyChanged != null) {
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Size"));
            }
            this._Size = value;
        }
    }
}
输出:

Changed: Name
Changed: Size

我认为你真正想要的是实现一个"observable dictionary"

你可能想要考虑的是实现一个字典TKey, TVal(你可以有一个通用的字典作为后备存储),并让Item的setter触发一个事件?