Подтвердить что ты не робот

Проблемы с расширением

Скажем, у меня есть 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;
        }
    } 
}

Эти методы, например, на самом деле ничего не делают.

Теперь рассмотрим этот фрагмент кода:

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 ?
        }
    }
}

Вопрос:

Я знаю, что будет выбран только один из методов расширения.
 Кто это будет? и почему?

Edit:

Это также беспокоит меня, но не так много, потому что это статический метод в статическом классе:

Как я могу выбрать определенный метод из определенного пространства имен?
 Обычно я использую Namespace.ClassNAME.Method()... Но это просто превосходит всю идею методов расширения. И я не думаю, что вы можете использовать Variable.Namespace.Method()

4b9b3361

Ответ 1

У меня был этот точный вопрос, поэтому я нашел этот пост два года спустя. Тем не менее, я думаю, важно отметить, что это не будет компилироваться и дать сообщение "Неисправный вызов" , если код, вызывающий методы дублирования расширений, не находится в том же пространстве имен, что и один из них.

Если OP должно было изменить пространство имен своего класса Blah на test1 или test2, тогда компиляция кода и расширение в том же пространстве имен, что и вызывающий, - даже если оба пространства имен представлены в usings. Поэтому, если Blah находится в пространстве имен test1, возвращается "1", и если Blah находится в пространстве имен test2, возвращается "2".

Я думаю, что это важно, чтобы добавить к вышеупомянутым ответам, потому что я думаю, что один основной вариант использования - это расширения в локальной библиотеке классов, которые ссылаются на внешние библиотеки расширений (например, разработчики совместно используют общую библиотеку утилиты, но имеют некоторые локальные пользовательские расширения, которые могут не совпадать с тем же именем). Поддерживая настраиваемые локальные расширения в том же пространстве имен, что и код, который их использует, вы можете поддерживать синтаксис вызова внутреннего вызова и не возвращаться к обработке их как вызовы статических методов.

Ответ 2

Никакой метод не будет выбран: вызов неоднозначен и не будет компилироваться.

Почему вы не можете сделать Namespace.ClassNAME.Method()? Конечно, нет ничего, что помешало бы вам рассматривать методы расширения как обычные статические методы, и на самом деле это единственный способ устранить двусмысленность и скомпилировать программу.

Ответ 3

Как говорит Джон, если оба они существуют, когда вы делаете компиляцию, компиляция просто терпит неудачу.

Но если во время компиляции существует только одна, а затем внешняя библиотека обновляется, чтобы добавить вторую, код, который вы скомпилировали, по-прежнему будет продолжать использовать первый. Это связано с тем, что компилятор превращает ваш код в длинную форму вызова namespace.classname.method.