c# - 扩展方法优先级

标签 c# extension-methods

我读自https://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx永远不会调用与基类型上现有方法具有相同名称和签名的扩展方法,但是“覆盖”扩展方法本身呢:

using System;
using System.Linq;
using System.Collections.Generic;


namespace ConsoleApplication1
{

    public class Program
    {

        public static void Main(string[] args)
        {

            var query = (new[] { "Hans", "Birgit" }).Where(x => x == "Hans");
            foreach (var o in query) Console.WriteLine(o);
        }

    }


    public static class MyClass
    {
        public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
        {
            foreach (var obj in source)
                if (predicate(obj)) yield return obj;
        }
    };

}

当我调试这个程序时,我确实遇到了我自己的扩展方法,而不是 System.Linq 提供的方法(尽管包含命名空间)。我错过了什么或者扩展方法是否也有优先级?

最佳答案

当编译器搜索扩展方法时,它从那些在与调用代码相同的命名空间中的类中声明的扩展方法开始,然后向外搜索,直到它到达全局命名空间。因此,如果您的代码位于命名空间 Foo.Bar.Baz 中,它将首先搜索 Foo.Bar.Baz,然后是 Foo.Bar,然后Foo,然后是全局命名空间。一旦找到任何符合条件的扩展方法,它将立即停止。如果它在同一步骤中找到多个符合条件的扩展方法,并且没有一个比另一个“更好”(使用正常的重载规则),那么您将收到一个编译时歧义错误。

然后(如果它没有找到任何东西)它考虑通过using 指令导入的扩展方法。因此,如果您将扩展方法移动到与您的扩展方法无关的不同 namespace ,您将因歧义而收到编译时错误(如果您使用 using 指令导入 namespace )或它只会找到 System.Linq 方法(如果您没有导入包含您的方法的命名空间)。

这在 C# 规范的第 7.6.5.2 节中指定。

关于c# - 扩展方法优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28698864/

相关文章:

c# - 如何在泛型的 where 子句中指定泛型类?

c# - 如何在 C# 中实现 "issue and submit back"模式?

c# - 如何向 MessageBox 添加扩展方法

c# - 您如何管理扩展方法的 namespace ?

c# - 仅使用扩展方法来设置默认属性是一种好习惯吗?

c# - Console.Error 和 Console.Out 不写入重定向文件流

c# - 如何从域(C# 代码)中删除计算机然后添加到工作组?

c# - 查找需要 InvokeRequired 的方法

c# - 如何返回 <TEnumerable, T> : where TEnumerable:IEnumerable<T>

c# - 将对象转换为 List<T> 以便能够使用扩展方法