扩展方法冲突

Yoc*_*mer 38 c# methods extension-methods conflict namespaces

假设我在2个不同的命名空间中有2个字符串扩展方法:

namespace test1
{
    public static class MyExtensions
    {
        public static int TestMethod(this String str)
        {
            return 1;
        }
    } 
}

namespace test2
{
    public static class MyExtensions2
    {
        public static int TestMethod(this String str)
        {
            return 2;
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

例如,这些方法实际上并没有做任何事情.

现在让我们考虑一下这段代码:

using System;
using test1;
using test2;

namespace blah {
    public static class Blah {
        public Blah() {
        string a = "test";
        int i = a.TestMethod(); //Which one is chosen ?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

我知道只会选择一种扩展方法.
会是哪一个?为什么?

编辑:

这也困扰我,但不是那么多,因为它毕竟是静态类中的静态方法:

如何从某个命名空间中选择某个方法?
通常我会使用Namespace.ClassNAME.Method()......但这只是超越了扩展方法的整个想法.我不认为你可以使用Variable.Namespace.Method()

Jon*_*Jon 29

将不会选择任何方法:调用是不明确的,不会编译.

你为什么不能这样做Namespace.ClassNAME.Method()?当然没有任何东西可以阻止你将扩展方法视为普通的静态方法,实际上这是你修复歧义并让程序编译的唯一方法.

  • @Yochai:编译器*不会*选择,因为如果两种扩展方法都可见,它将拒绝编译。正如你所说,`variable.Namespace.Method()` 在语法上是无效的,所以它也不会编译。 (2认同)

mdi*_*bio 26

我有这个确切的问题所以我在两年后找到了这个帖子.但是,我认为重要的是要注意,如果调用重复扩展方法的代码与其中一个名称不在同一名称空间中,则只会编译并给出" 调用不明确 "错误.

如果OP要将其类Blah的名称空间更改为test1或者test2,则代码编译,并且使用与调用者相同的名称空间中的扩展名 - 即使两个名称空间都表示在usings.因此,如果Blahtest1命名空间中,则返回"1",如果Blahtest2命名空间中,则返回"2".

我认为这对于添加上述答案很重要,因为我认为一个主流用例是在引用外部扩展库的本地类库中有扩展(例如devs共享一个公共实用程序库,但有一些本地自定义扩展,可能在不知不觉中有相同的名字).通过将自定义本地扩展保持在与使用它们的代码相同的命名空间中,您可以维护扩展调用语法,而不必将其视为静态方法调用.

  • NB.命名空间是分层的,因此如果要在整个项目中覆盖某些第三方库的扩展,可以将自己的扩展放在项目使用的顶级命名空间中 (2认同)

Rob*_*evy 12

正如Jon所说,如果在编译时存在这两种情况,编译就会失败.

但是,如果在编译时只存在一个,并且外部库稍​​后会更新以添加第二个,则编译的代码仍将继续使用第一个.这是因为编译器会将您的代码转换为调用namespace.classname.method的缩写形式.