我想知道为什么给定代码的输出(在
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类上实现的等号运算符将比较封装(动作)中的实际目标.