为什么不能注册作为参数传递的事件?

本文关键字:事件 参数传递 不能 注册 为什么 | 更新日期: 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,因为_myEventMyClass2构造函数返回后为空。

MyClass2的构造函数中,当您执行_event += MyFunction时,可以有效地简化为:

_event = (Action)Delegate.Combine(_event, (Action)MyFunction);

所以现在在构造函数中你有一个全新的引用,除非你在参数中添加ref关键字,否则它不会被传递回来。

引用有问题。试一试:

public MyClass2(ref Action _event)

:

当编译器编译代码时,它将event生成为两个方法:add_YourEventremove_YourEvent,以及一个私有委托,该委托包含对注册委托列表的头的引用。

出现问题是因为当你将对象作为参数传递给方法时,它们实际上是两个不同的内存块。对方法内部引用的更改不会影响在MyClass1中声明的变量。所以当这行执行时:

_event += MyFunction;

引用从null更改为对委托的引用,但这只影响传入参数。变量的引用(在MyClass1中声明)不会改变。