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

时间:2015-07-19 03:24:55

标签: c# events delegates nullreferenceexception

这是我的代码:

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参数,它可以正常工作。那是为什么?

2 个答案:

答案 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_YourEventremove_YourEvent以及包含对头部的引用的私有代理登记代表名单。

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

_event += MyFunction;

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