我想知道为什么给定代码的输出(在
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; }
总是:
False True
在这两种情况下,我都天真地期望它是真的.
解决方法
这是编译到IL然后反编译回C#时的外观.请注意,在这两种情况下,都有新的Action(Main) – 一个新的引用对象(delegate),其中包含指向实际存储方法的指针.
private static void Main() { Program.Compare1(new Action(Program.Main)).Dump(); Program.Compare2(new Action(Program.Main)).Dump(); Console.ReadLine(); } private static bool Compare1(Delegate x) { return x == new Action(Program.Main); } private static bool Compare2(Action x) { return x == new Action(Program.Main); }
如果我们看看CIL,前者使用ceq(参考比较),后者使用call bool [mscorlib] System.Delegate :: op_Equality(class [mscorlib] System.Delegate,class [mscorlib] System.Delegate)to比较代表
首先返回false,因为包含代理的动作是两个不同的引用对象.
第二个返回true,因为在Delegate类上实现的等号运算符将比较封装(动作)中的实际目标.