为什么不能注册作为参数传递的事件?
本文关键字:事件 参数传递 不能 注册 为什么 | 更新日期: 2023-09-27 18:03:20
这是我的代码:
using System.IO;
using System;
public class MyClass1{
event Action _myEvent;
public MyClass1(){
var m = new MyClass2(_myEvent);
_myEvent();
}
}
public class MyClass2{
public MyClass2(Action _event){
_event += MyFunction;
}
void MyFunction(){
Console.WriteLine("Hi");
}
}
class Program
{
static void Main()
{
var m = new MyClass1();
}
}
似乎MyClass2没有注册到传递的参数_myEvent。即使MyClass2应该被订阅,调用_myEvent也会导致NullReferenceException。如果我将_myEvent设为公共,并让MyClass2直接注册到它,而不使用传递给它的事件参数,它就能正常工作。为什么呢?
您将获得NullReferenceException
,因为_myEvent
在MyClass2
构造函数返回后为空。
在MyClass2
的构造函数中,当您执行_event += MyFunction
时,可以有效地简化为:
_event = (Action)Delegate.Combine(_event, (Action)MyFunction);
所以现在在构造函数中你有一个全新的引用,除非你在参数中添加ref
关键字,否则它不会被传递回来。
引用有问题。试一试:
public MyClass2(ref Action _event)
:
当编译器编译代码时,它将event
生成为两个方法:add_YourEvent
和remove_YourEvent
,以及一个私有委托,该委托包含对注册委托列表的头的引用。
出现问题是因为当你将对象作为参数传递给方法时,它们实际上是两个不同的内存块。对方法内部引用的更改不会影响在MyClass1
中声明的变量。所以当这行执行时:
_event += MyFunction;
引用从null
更改为对委托的引用,但这只影响传入参数。变量的引用(在MyClass1
中声明)不会改变。