为什么我不能注册到作为参数传递的事件?
Why can I not register to events passed as arguments?
这是我的代码:
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 public 并让 MyClass2 直接注册到它而不使用传递给它的事件参数,它可以正常工作。这是为什么?
您正在获取 NullReferenceException
,因为 _myEvent
在 MyClass2
构造函数的 return 之后为空。
在 MyClass2
的构造函数中,当您执行 _event += MyFunction
时,这实际上是 shorthand for:
_event = (Action)Delegate.Combine(_event, (Action)MyFunction);
所以现在在构造函数中你有一个全新的引用,除非你将 ref
关键字添加到参数中,否则它不会被传回。
引用有问题。尝试:
public MyClass2(ref Action _event)
解释:
当编译器编译代码时,它将 event
生成为 2 个方法:add_YourEvent
和 remove_YourEvent
以及 包含对头部引用的私有委托 个注册代表列表。
出现问题是因为当您将对象作为参数传递给方法时,它们实际上是 2 个不同的内存块。对方法内引用的更改不会影响您在 MyClass1
中声明的变量。所以当这一行被执行时:
_event += MyFunction;
引用从null
更改为对委托的引用,但这只会影响传入的参数。您的变量引用(在 MyClass1
中声明)没有改变。
这是我的代码:
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 public 并让 MyClass2 直接注册到它而不使用传递给它的事件参数,它可以正常工作。这是为什么?
您正在获取 NullReferenceException
,因为 _myEvent
在 MyClass2
构造函数的 return 之后为空。
在 MyClass2
的构造函数中,当您执行 _event += MyFunction
时,这实际上是 shorthand for:
_event = (Action)Delegate.Combine(_event, (Action)MyFunction);
所以现在在构造函数中你有一个全新的引用,除非你将 ref
关键字添加到参数中,否则它不会被传回。
引用有问题。尝试:
public MyClass2(ref Action _event)
解释:
当编译器编译代码时,它将 event
生成为 2 个方法:add_YourEvent
和 remove_YourEvent
以及 包含对头部引用的私有委托 个注册代表列表。
出现问题是因为当您将对象作为参数传递给方法时,它们实际上是 2 个不同的内存块。对方法内引用的更改不会影响您在 MyClass1
中声明的变量。所以当这一行被执行时:
_event += MyFunction;
引用从null
更改为对委托的引用,但这只会影响传入的参数。您的变量引用(在 MyClass1
中声明)没有改变。