I am wondering why the output of the given code (execute it in LinqPad)
void Main() {
Compare1((Action)Main).Dump();
Compare2(Main).Dump();
}
bool Compare1(Delegate x) {
return x == (Action)Main;
}
bool Compare2(Action x) {
return x == Main;
}
is always:
False
True
I have naively expected it to be True
in both cases.
This is how it looks when compiled to IL and then decompiled back to C#. Note that in both cases there's
new Action(Main)
- a new reference object (delegate) with pointer to actual method stored inside.If then we take a look into CIL, the former uses
ceq
(reference comparison) and the latter usescall bool [mscorlib]System.Delegate::op_Equality(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
to compare delegates.First returns
false
because actions wrapping your delegates are two distinct reference objects.Second returns
true
as the equality operator implemented on theDelegate
class compares actual targets inside wrappers (actions).The
false
result is related to the fact that the Compare1() method performs reference comparison on two different object (compilator shows the corresponding warning):You can avoid the issue using the following code: