2015-07-19 64 views
1

这是我的代码:为什么我不能注册作为参数传递的事件?

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直接注册到它,而不使用传递给它的事件参数,它就可以正常工作。这是为什么?

+0

可能重复[什么是NullReferenceException,我该如何解决它?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-doi-i-fix-它) –

+0

你认为我怎么创造它?我从来没有见过任何人“创造”一个事件。如果我将事件公开并直接注册给它,而不使用参数,那么一切正常。 –

+0

你公开哪部分? – DavidG

回答

3

您正在获得NullReferenceException,因为_myEvent在从MyClass2构造函数返回后为null。所以,现在

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

构造函数中的你有这将不会获得通过回,除非你添加一个全新的基准:

在构造为MyClass2,当你做_event += MyFunction,这是有效的简写ref关键字到参数。

+0

'_event = Delegate.Combine(_event,(Action)MyFunction);'如果你想编译它。 – sstan

+0

@sstan几乎但不完全,但我编辑了一个可编译的版本。 – DavidG

2

引用有问题。尝试:

public MyClass2(ref Action _event)

说明

当编译器编译的代码,它产生event成2种方法:add_YourEventremove_YourEvent包含参考到的头部私人代表注册代表名单。

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

_event += MyFunction; 

基准电压从null变为一个对委托的引用,但是这只会影响传入的参数。您的变量参考(在MyClass1中声明)不会更改。

+0

当调用'_event + = MyFunction;'时,'_event'只是一个委托,而不是一个事件,尽管它的名字。所以在这种情况下它并不真正调用add_YourEvent方法。 – sstan

相关问题