I think what might clarify is how events work. (Note, this is a long answer, tailored to your example. For something shorter, but less specific, see https://stackoverflow.com/a/33964976/8105643)
The event
keyword is really just a nice syntax for setting up an EventHandler Delegate.
Now we understand that events are just special syntax delegates, we can explain how subscribing to an event actually works, and show how the two examples you gave are actually quite similar:
In your first example, you have essentially this situation:
public class DelegateCombineExample {
public static void Method1()
{
Console.WriteLine("Running Method 1");
}
public static void Method2()
{
Console.WriteLine("Running Method 2");
}
public void Main() {
var action = Method1;
action += Method2;
action();
}
}
The real question is what is +=
doing here?
Well, we can answer that! Here is a sharplab.io that shows the lowered c# code for the above block.
public delegate void MyDelegate();
public class DelegateCombineExample
{
[CompilerGenerated]
private static class <>O
{
public static Action <0>__Method1;
public static Action <1>__Method2;
}
public static void Method1()
{
Console.WriteLine("Running Method 1");
}
public static void Method2()
{
Console.WriteLine("Running Method 2");
}
public void Main()
{
Action a = <>O.<0>__Method1 ?? (<>O.<0>__Method1 = new Action(Method1));
a = (Action)Delegate.Combine(a, <>O.<1>__Method2 ?? (<>O.<1>__Method2 = new Action(Method2)));
a();
}
}
This looks complicated, but much of this is noise for us at the moment. The piece we're interested in is where did the +=
go? It's gone!
Instead, we have this new Delegate.Combine
. This method call joins together the current delegate stored in action
and combines it with Method2
when we do action += Method2
.
(incidentally, there is a Delegate.Remove
that gets called for -=
).
So, now that we know that in the first example, "subscribing" really just means combining the delegates with Delegate.Combine
, so that invoking action
means invoking both delegates, how does example 2 work? Let's see!
In a fashion similar to the first, let's create a sharplab for example 2 to see what's going on:
public delegate void MyDelegate();
public class EventExample {
public event MyDelegate MyEvent;
public static void Method1()
{
Console.WriteLine("Running Method 1");
}
public void M() {
MyEvent += Method1;
MyEvent();
}
}
This time I'll jsut take an excerpt from the generated code, since there's a lot:
public class EventExample
{
[CompilerGenerated]
private static class <>O
{
public static MyDelegate <0>__Method1;
}
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private MyDelegate m_MyEvent;
public event MyDelegate MyEvent
{
[CompilerGenerated]
add
{
MyDelegate myDelegate = this.MyEvent;
while (true)
{
MyDelegate myDelegate2 = myDelegate;
MyDelegate value2 = (MyDelegate)Delegate.Combine(myDelegate2, value);
myDelegate = Interlocked.CompareExchange(ref this.MyEvent, value2, myDelegate2);
if ((object)myDelegate == myDelegate2)
{
break;
}
}
}
[CompilerGenerated]
remove // hidden for brevity
}
public static void Method1()
{
Console.WriteLine("Running Method 1");
}
public void M()
{
MyEvent += <>O.<0>__Method1 ?? (<>O.<0>__Method1 = new MyDelegate(Method1));
this.MyEvent();
}
}
Alright, in this case, we still have a +=
on the event! Does this mean they're different? A little, but not much!
We also have this compiler-generated add
on the MyEvent
event. This is what gets called for +=
in the code. If we inspect that add
's body, we can see that our old friend Delegate.Combine
is what shows up to add the subscriber method (value
) onto the current event handler (myDelegate2
).
So, all of this is to explain: These two examples are very similar! Your ChatGPT output uses the event
keyword to set up a special type of delegate, but fundamentally, the +=
you use to combine delegates in example 1 works very similarly to the +=
that adds subscribers to MyEvent
in example 2!
in reply to https://discord.com/channels/143867839282020352/169726586931773440/1175462855320018964