Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why C# events cannot be directly subscribed to other events

Why does the following code not print "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 => {};   

    }
}

But if I replace line

a.Evnt += Evnt;

with

a.Evnt += v => Evnt(v);

everything works fine.

If this is forbidden to do so, what meaning has subscribing one event to another, and why are there no compilation errors or warnings when doing so?

like image 739
drozdov Avatar asked Nov 04 '25 21:11

drozdov


1 Answers

It fails for the same reason this code prints "2":

int x = 2;
int y = x;

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

x = 3;
a();

Here, your event handler is the value of a.Evnt at the time of assignment -- whatever a has for Evnt at the time when you pass a into B's constructor, that's what B gets for an event handler.

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

It actually works fine -- it does what you told it to. It's just that you thought you were telling it to do something different.

Here, you have a handler that evaluates Evnt itself, at whatever time the handler is executed. So with this one, if a.Evnt is changed in the mean time, you'll see the output from the new value of a.Evnt.

public B(A a)
{
    a.Evnt += v => Evnt(v);
}

Rewrite B like this, and you'll get a clearer picture:

public class B
{

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

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

}

The title of your question isn't well phrased; you're not assigning an event, you're assigning an event handler. Also, "this does not work" is not a useful way to describe a problem. There is an infinity of ways for things not to work. My first assumption was that your code wouldn't even compile. Next time, please describe the behavior you expected to see, and what you actually saw instead. Say whether it failed to compile, or threw an exception at runtime, or just quietly did something you didn't anticipate. If there's an error message or an exception message, provide the text of the message.

like image 137
15ee8f99-57ff-4f92-890c-b56153 Avatar answered Nov 07 '25 10:11

15ee8f99-57ff-4f92-890c-b56153



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!