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

本文关键字:扩展 方法 重载 何解决 解决 | 更新日期: 2023-09-27 17:56:33

我有一个代码片段如下:

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);
    }
}

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

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

所以我的问题是,C# 或 .net 框架中是否有规则来确定,如果有多个匹配项,将调用哪个扩展方法?这与过载解决规则还是其他原因有关?

非常感谢。

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

与所有其他方法一样,重载规则适用于扩展方法。 使用N是因为它是更好的匹配。 M可能具有可选参数,但无参数选项更适合,因为规则倾向于参数最少的选项。

从命名参数和可选参数(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);
        }
    }
}

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

这与扩展方法无关。在重载解析算法的平局中断阶段,与需要应用所述默认参数以匹配调用的方法相比,首选匹配调用而不应用默认参数的方法。

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

[...]如果MP的所有参数都有一个对应的参数,而默认参数需要替换MQ中的至少一个可选参数,那么MP比MQ更好。