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

C#事件处理是如何实现的?,c#,event-handling,C#,Event Handling,使用赋值运算符更新DataGridView.DataSource时,将调用DataSourceChanged事件处理程序。您不能在C#中重载赋值操作,那么如何在内部调用事件处理程序呢 public void foo(){ this.dataGridView.DataSourceChanged += new EventHandler(bar); this.dataGridView.DataSource = dt; } //this handler is called after

使用赋值运算符更新
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) {}
这完全取决于事件的功能,但我认为事件就像属性一样-除了getter和setter之外,您有
add
remove
操作,每个操作都让代理订阅或取消订阅事件

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

有关更多信息,请参阅我的


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

不清楚你在问什么。如果您询问属性设置器如何做某事:属性设置器是一种方法。它与任何其他方法一样有效。在这种情况下,当调用属性setter时,它会检查是否需要引发事件,如果需要,则会引发事件

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

从底部开始


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

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


我建议找一个简单的教程,介绍如何为其他课程提供自己的活动。它将使您更好地了解事件的提供者需要如何工作,而不需要太多的细节。

数据源
是作为属性实现的

private object _dataSource;
public object DataSource {
    get
    {
        return _dataSource;
    }
    set
    {
        if (value != _dataSource) {
            _dataSource = value;
            UpdateTheDataGridView();
            RaiseTheDataSourceChangedEvent();
        }
    }
}
读/写属性是两个方法的集合,当您访问该属性时,会自动调用这两个方法
set
赋值时,读取属性时,
get

private object _dataSource;
public object DataSource {
    get
    {
        return _dataSource;
    }
    set
    {
        if (value != _dataSource) {
            _dataSource = value;
            UpdateTheDataGridView();
            RaiseTheDataSourceChangedEvent();
        }
    }
}
还要注意,只有在为数据源分配了不同的内容时,才会注册更改。这意味着您无法通过重新分配相同的数据源来刷新网格

var list = new List<string> { "a", "b", "c" };
dgv.DataSource = list;

list.Add("d");
dgv.DataSource = list; // Does not work.
var list=新列表{“a”、“b”、“c”};
dgv.DataSource=列表;
列表。添加(“d”);
dgv.DataSource=list;//不起作用。
解决方法:

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

dgv.DataSource=null;// Datasource是一个属性,在集合中调用事件处理程序


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

这是您遇到的问题还是一般性问题?