C#如何解决不同的扩展方法重载?

vik*_*ata 1 c# overloading match

我有一个代码片段如下:

public static class M
{
    public static int Plus(this int i, int p=6)
    {
        return i + p;
    }
}
public static class N
{
    public static int Plus(this int i)
    {
        return i + 10;
    }
}
class Program
{
    static void Main()
    {
        int i = 3.Plus();
        Console.WriteLine(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行程序,输出"13",表示调用N类的扩展方法.为什么M类的方法不匹配?

然后,如果我删除N类,OK,调用类M的扩展方法,它会按预期输出"9".

所以我的问题是,是否有一个规则在C#或.net框架中确定,如果有多个匹配,将调用哪个扩展方法?这是否与重载解析规则或其他相关?

非常感谢.

Dav*_*rno 9

与所有其他方法一样,相同的重载规则适用于扩展方法.N使用是因为它是一个更好的匹配.M可能有一个可选参数,但是no参数选项更适合,因为规则支持使用最少参数的选项.

命名参数和可选参数(C#编程指南):

如果判断两个候选者同样好,则优先选择没有可选参数的候选者,该参数在调用中被省略.这是对具有较少参数的候选者的重载分辨率的一般偏好的结果.

然而,正如Eric Lippert的博客中描述的那样,"接近"也会与扩展方法一起发挥作用:

这样做的结果是,如果您将代码重构为:

namespace X
{
    public static class N
    {
        public static int Plus(this int i)
        {
            return i + 10;
        }
    }
}

namespace ConsoleApplication1
{
    public static class M
    {
        public static int Plus(this int i, int p = 6)
        {
            return i + p;
        }
    }

    internal class Program
    {
        private static void Main()
        {
            int i = 3.Plus();
            Console.WriteLine(i);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后显示的数字是9.换句话说,选择具有可选参数的版本,因为它在同一名称空间中,因此"更接近".


The*_*kis 5

这与扩展方法无关.在重载决策算法的打破平局阶段,与不需要应用默认参数的调用匹配的方法优于需要应用所述默认参数以匹配调用的方法.

正如C#规范所述,在第154页:

[...]如果MP的所有参数都有相应的参数,而默认参数需要替换MQ中的至少一个可选参数,那么MP优于MQ.