委托与事件的本质

委托的弊端

1.调用委托时,如果其中的一个委托报错,则后面的不会被调用;
2.只有最后一个的返回值才会作为委托的返回值;
3.因为是数组,所以remove 的复杂度是O(n);并且是从后往前遍历
4.线程不安全。

委托为什么不等于函数指针?

1.委托可以“指向”多个函数;
2.委托可以指向同一个函数多次;
3.函数是包含在类中的,所以函数引用也包含了所在对象的信息;而C/C++的函数指针只是函数的入口地址。

事件的本质

1.将委托以私有变量的形式封装在类内,不让外面访问;
2.对于委托进行了封装,从而定义add与remove方法;
3.在add与remove中通过互锁的方式提供了线程安全性。

下面代码是Action泛型 in 逆变的代码

void Main()
{
	Demo demo = new Demo();
	demo.NotifyEvent+=F1;
	demo.NotifyEvent+=F2;
	demo.NotifyEvent+=F1;
	demo.NotifyEvent+=F2;
	demo.NotifyEvent+=F3;
	demo.InvokeAction();
	void F1(A a)
	{
		nameof(F1).Dump();
	}
	void F2(B b)
	{
		nameof(F2).Dump();
	}
	void F3(B b)
	{
		throw new Exception("Error");
		nameof(F2).Dump();
	}
}
class Demo
{
	private List<Action<B>> _action = new();
	public event Action<B>? NotifyEvent
	{
		add
		{
			_action.Add(value);
		}
		remove
		{
			_action.Remove(value);
		}
	}
	public void InvokeAction()
	{
		foreach(var action in _action)
		{

			action?.Invoke(null);
		}
	}
}
		
class A{}
class B:A{}

MulticastDelegate源代码:https://source.dot.net/#System.Private.CoreLib/src/System/MulticastDelegate.cs,115d292376227fdb

笔记来源:https://www.bilibili.com/video/BV1AT411U7H2


C#
  • 作者: Mahiru (联系作者)
  • 发表时间: 2024/04/02 21:58
  • 更新时间: 2024/04/02 22:20
  • 留言 顶部