重载解析的精确规则是什么==
两个委托类型表达式之间?
考虑以下代码(其中using System;
是需要的):
static class ProgramA
{
static void TargetMethod(object obj)
{
}
static void Main()
{
Action<object> instance1 = TargetMethod;
Action<object> instance2 = TargetMethod;
Action<string> a1 = instance1;
Action<Uri> a2 = instance2;
Console.WriteLine((object)a1 == (object)a2);
Console.WriteLine((Delegate)a1 == (Delegate)a2);
Console.WriteLine((Action<object>)a1 == (Action<object>)a2);
Console.WriteLine(a1 == a2); // warning CS0253: Possible unintended reference comparison; to get a value comparison, cast the right hand side to type 'System.Action<string>'
}
}
解释:
instance1
and instance2
是同一运行时类型的两个单独实例,通用Action<in T>
这是逆变 in T
。这些实例是不同的,但是Equals
因为他们有相同的目标。
a1
and a2
与instance1
and instance2
,但由于逆变Action<in T>
存在implicit参考转换自Action<object>
给每一个Action<string>
and Action<System.Uri>
.
现在,C# 语言规范(以及其他重载)具有这些operator ==
:
bool operator ==(object x, object y); // §7.10.6
bool operator ==(System.Delegate x, System.Delegate y); // §7.10.8
当前的 Visual C# 编译器通过简单地检查引用是否相同来实现第一个(IL 实际上并不调用 mscorlib 方法,例如object.ReferenceEquals
,但这会给出相同的结果),同时它通过调用实现第二个Delegate.op_Equality method http://msdn.microsoft.com/en-us/library/system.delegate.op_equality.aspx即使它是由 C# 语言规范定义的,它看起来也像是该程序集中的“用户定义”运算符,因此可能不是规范意义上的“用户定义”(?)。
请注意,§7.10.8 有点令人困惑,因为它说“每个委托类型隐式提供以下预定义的比较运算符”然后给操作员提供(System.Delegate, System.Delegate)
签名。那只是one运算符,而不是“每种”委托类型的运算符?这对于我的问题似乎很重要。
前三名并不奇怪WriteLine
write False
, True
and True
,分别考虑到我上面所说的。
问题: