如何使用onChange事件扩展类型

时间:2015-05-14 16:09:41

标签: c# winforms

具体来说我想在字符串类中添加一个onChange事件,我该怎么做?

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

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

更新

我的字典目前是字符串,但我可以将其更改为int或dynamic而不会有太大的麻烦。

3 个答案:

答案 0 :(得分:2)

将这样的事件添加到字符串是没有意义的,因为字符串是不可变的。您无法更改其内容,只能使用所需内容创建新字符串。

现在,您可以修改字符串变量,方法是更改​​它指向的字符串值。例如,在此代码中:

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

通过连接两个字符串“Hello”和“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”被丢弃。

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

答案 1 :(得分:1)

字符串是密封的。你不能从他们那里继承。无论如何,它们是不可变的,永远不会改变。您可以做的最接近的事情是使用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

答案 2 :(得分:1)

我认为你真正想要的是实现一个&#34;可观察字典&#34;。

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