扩展方法优先级 [英] Extension method priority

查看:108
本文介绍了扩展方法优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I read from https://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx that extension methods with same name and signature as existing ones on the base type are never called, but what about "overriding" an extension-method itself:

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提供的方法(尽管包括名称空间)。是我错过了什么还是扩展方法的优先级?

When I debug this program I DO run into my own extension-method rather then that one provided by System.Linq (although the namespace is included). Did I miss anything or is there also a priority for extension-methods?

推荐答案

当编译器搜索扩展方法时,它会启动与在与调用代码相同的名称空间中的类中声明的那些,然后向外进行处理,直到到达全局名称空间。因此,如果您的代码位于名称空间 Foo.Bar.Baz 中,它将首先搜索 Foo.Bar.Baz ,然后 Foo.Bar ,然后是 Foo ,然后是全局名称空间。找到任何符合条件的扩展方法后,它将立即停止。如果它在同一步骤中找到了多个合格的扩展方法,并且没有一个比其他方法更好(使用正常的重载规则),那么您会因为模棱两可而出现编译时错误。

When the compiler searches for extension methods, it starts with those declared in classes in the same namespace as the calling code, then works outwards until it reaches the global namespace. So if your code is in namespace Foo.Bar.Baz, it will first search Foo.Bar.Baz, then Foo.Bar, then Foo, then the global namespace. It will stop as soon as it finds any eligible extension methods. If it finds multiple eligible extension methods in the same step, and none is "better" than the other (using normal overloading rules) then you'll get a compile-time error for ambiguity.

然后(如果未找到任何内容)将考虑使用使用指令导入的扩展方法。因此,如果将扩展方法移至与您的无关的另一个命名空间,则由于歧义(如果使用使用指令),否则只会找到 System.Linq 方法(如果未导入包含方法的命名空间)。

Then (if it hasn't found anything) it considers extension methods imported by using directives. So, if you move your extension method to a different namespace which is unrelated to yours, you'll either get a compile-time error due to ambiguity (if you imported the namespace with a using directive) or it will only find the System.Linq method (if you didn't import the namespace containing your method).

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

This is specified in section 7.6.5.2 of the C# specification.

这篇关于扩展方法优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆