为什么C#事件不能直接订阅其他事件

dro*_*dov 3 c# events delegates

为什么以下代码不打印"Hello,World!"?

using System;

namespace Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var a = new A();
            var b = new B(a);
            b.Evnt += val => Console.WriteLine(val);
            a.Do();
        }
    }

    public class A
    {
        public void Do()
        {
            Evnt("Hello, World!");   
        }

        public event Action<string> Evnt = v => {};   
    }

    public class B
    {

        public B(A a)
        {
            a.Evnt += Evnt; // this does not work
        }

        public event Action<string> Evnt = v => {};   

    }
}
Run Code Online (Sandbox Code Playgroud)

但如果我换线

a.Evnt += Evnt;
Run Code Online (Sandbox Code Playgroud)

a.Evnt += v => Evnt(v);
Run Code Online (Sandbox Code Playgroud)

一切正常.

如果禁止这样做,那么将一个事件订阅到另一个事件有什么意义,为什么这样做时没有编译错误或警告?

15e*_*153 5

它失败的原因与此代码打印"2"的原因相同:

int x = 2;
int y = x;

Action a = () => Console.WriteLine(y);

x = 3;
a();
Run Code Online (Sandbox Code Playgroud)

在这里,你的事件处理程序的价值a.Evnt 在分配的时间 -无论aEvnt当你经过的时候a进入B的构造,这就是B一个事件处理程序获取.

public B(A a)
{
    a.Evnt += Evnt; // this does not work
}
Run Code Online (Sandbox Code Playgroud)

它实际上工作正常 - 它做你告诉它的.只是你以为你是在告诉它要做些不同的事情.

在这里,您有一个处理程序Evnt,可以在执行处理程序的任何时间自行计算.所以有了这个,如果a.Evnt在平均时间内改变,你会看到新值的输出a.Evnt.

public B(A a)
{
    a.Evnt += v => Evnt(v);
}
Run Code Online (Sandbox Code Playgroud)

像这样重写B,你会得到更清晰的画面:

public class B
{

    public B(A a)
    {
        a.Evnt += Evnt; // this does not work
    }

    public event Action<string> Evnt = v => { Console.WriteLine("Original"); };

}
Run Code Online (Sandbox Code Playgroud)

你问题的标题没有很好地表达; 你没有分配一个事件,你正在分配一个事件处理程序.此外,"这不起作用"不是描述问题的有用方法.事情无穷无尽.我的第一个假设是你的代码甚至不会编译.下一次,请描述您希望看到的行为,以及您实际看到的内容.说它是否无法编译,或在运行时抛出异常,或者只是悄悄地做了一些你没想到的事情.如果出现错误消息或异常消息,请提供消息文本.