C#事件处理是如何实现的

本文关键字:实现 何实现 事件处理 | 更新日期: 2023-09-27 18:29:15

使用赋值运算符更新DataGridView.DataSource时,会调用DataSourceChanged事件处理程序。您不能在C#中重载赋值操作,那么如何在内部调用事件处理程序呢?

public void foo(){
    this.dataGridView.DataSourceChanged += new EventHandler(bar);
    this.dataGridView.DataSource = dt;
}
//this handler is called after datasource changes
private void bar(object sender, EventArgs e) {}

C#事件处理是如何实现的

DataSource实现为一个属性。

private object _dataSource;
public object DataSource {
    get
    {
        return _dataSource;
    }
    set
    {
        if (value != _dataSource) {
            _dataSource = value;
            UpdateTheDataGridView();
            RaiseTheDataSourceChangedEvent();
        }
    }
}

读/写属性是一组两个方法,当您访问该属性时会自动调用它们;分配值时为set,读取属性时为get

另外请注意,只有当您为数据源分配了不同的内容时,才会注册更改。这意味着您无法通过重新分配相同的数据源来刷新网格。

var list = new List<string> { "a", "b", "c" };
dgv.DataSource = list;
list.Add("d");
dgv.DataSource = list; // Does not work.

解决方法:

list.Add("d");
dgv.DataSource = null; // <== this does the trick.
dgv.DataSource = list;

您要问什么还不完全清楚。如果你在问属性设置器如何做某事:属性设置器是一个方法。它的工作原理和其他任何方法一样。在这种情况下,当调用属性setter时,它会检查是否需要引发事件,如果需要,则引发事件。

如果你问事件本身是如何实现的,Jon的文章当然很好。如果您正在寻找关于事件如何在C#中实现以及实现如何随时间变化的附加技术分析,请参阅Chris Burrows关于以下主题的博客文章:

http://blogs.msdn.com/b/cburrows/archive/tags/events/

从底部开始。

Chris是开发人员,他设计并实现了对编译器的语义分析和代码生成的许多更改。

它的作用完全取决于事件,但我认为事件就像属性一样——除了有addremove操作,而不是getter和setter,每个操作都接受委托来订阅或取消订阅事件。

C#中类似事件的字段使用委托的字段来实现事件,并修复了添加/删除实现——有点像自动实现的属性。但是您可以在addremove处理程序中执行任何您喜欢的操作。

有关更多信息,请参阅我关于代表和活动的文章。

至于数据源本身——它不是分配字段——它是分配给属性,所以,它可以做任何它想做的事情,包括引发DataSourceChanged事件。

数据源是一个属性,在集合中调用事件处理程序。

您可以使用ilspy来查看这是如何实际实现的。

事件处理程序在内部被调用,因为提供事件的类(在本例中为DataGridView)在其代码中的某个点显式激发事件。DataSource的属性setter听起来像是激发这个特定事件的合适位置,尽管我没有在源代码中查看以进行确切验证。

我建议查阅一个简单的教程,了解如何为另一个班级提供自己的活动。它将让你更好地了解事件的提供者需要如何工作,而不需要太多的细节。