这是我的代码:
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直接注册它而不使用传递给它的event参数,它可以正常工作。那是为什么?
答案 0 :(得分:3)
您收到NullReferenceException
,因为从_myEvent
构造函数返回后MyClass2
为空。
在MyClass2
的构造函数中,当您执行_event += MyFunction
时,这实际上是简写:
_event = (Action)Delegate.Combine(_event, (Action)MyFunction);
所以现在在构造函数中你有一个全新的引用,除非你将ref
关键字添加到参数中,否则它将不会被传回。
答案 1 :(得分:2)
引用存在问题。尝试:
public MyClass2(ref Action _event)
<强>解释强>:
当编译器编译代码时,它会将event
生成为2种方法:add_YourEvent
和remove_YourEvent
以及包含对头部的引用的私有代理登记代表名单。
出现问题是因为当您将对象作为参数传递给方法时,它们实际上是 2个不同的内存块。对方法内部引用的更改不会影响MyClass1
中声明的变量。所以当这一行执行时:
_event += MyFunction;
引用从null
更改为对委托的引用,但这仅影响传入的参数。您的变量引用(在MyClass1
中声明)不会更改。