2015-11-09 2 views
2

У меня есть этот метод расширенияметод расширения перегрузки

public static class Extensions 
{ 
    public static void ConsoleWriteLine(this object Value) 
    { 
     Console.WriteLine(Value); 
    } 
} 

для целочисленных значений У меня есть небольшая модификация

public static void ConsoleWriteLine(this int Value) 
{ 
    Console.WriteLine("Integer: " + Value); 
} 

мой вопрос:, когда я пишу int x = 1; x.ConsoleWriteLine();, что делает решение взять второе расширение в этом случае? int является object, а также

ответ

5

Что принимает решение о принятии второго продления в этом случае?

Когда у компилятора есть несколько допустимых методов на выбор, он использует набор правил разрешения перегрузки, чтобы определить, к какому методу он должен привязываться. Второй метод расширения соответствует вызывающей сигнатуре точно, поэтому он выбран. Так как любой другой тип напрямую конвертируемый в object, будет выбрано первое расширение. Другие числовые типы неявно конвертируются в int, но неявное преобразование не «лучше», чем прямое преобразование в родительский класс.

Я считаю, что отношение спецификация здесь 7.5.3.2:

7.5.3.2 Лучше член функции

Для целей определения лучшего члена функции, урезанный список аргументов A построена, содержащая только сами выражения аргументов в том порядке, в котором они появляются в списке исходных аргументов. списки параметров для каждого из членов кандидатов функции построены следующим образом:

...

Дано список аргументов А с набором аргументов выражений {E1, E2, ..., EN} и два применимых члена функции MP и MQ с типами параметров {P1, P2, ..., PN} и {Q1, Q2, ..., QN}, MP определены как лучший функциональный элемент, чем MQ, если

  • для каждого аргумента, неявное преобразование из EX в QX не лучше, чем неявное преобразование из EX в PX, и

Поскольку «конверсии» от int к int «лучше», что переход от int к object, выбирается перегрузка int.

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

2

По MSDN:

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

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

+0

Что означает нижний уровень? Все расширения здесь находятся в одном пространстве имен. – usr

+0

@usr Сверху вверх в иерархии классов. То есть сначала он будет искать методы расширения в типе 'System.Int32', и если ни один из них не будет сопоставлен, он затем продолжит поиск в' System.Object' –

+0

Не думайте, что это вообще так. Не следует ли перегружать разрешение смотреть на все аргументы? MSDN часто ужасно расплывчато. Здесь никто не может сказать, что означает это предложение. – usr

0

Ну, в этом случае:

public static class Extensions 
{ 
public static void ConsoleWriteLine(this object Value) 
{ 
    Console.WriteLine(Value); 
} 
} 

Вы пишете метод расширения для объекта. См:

this object Value 

В вашем другом методе расширения, вы пишете расширение для целого числа.

public static void ConsoleWriteLine(this int Value) 
{ 
    Console.WriteLine("Integer: " + Value); 
} 

Поскольку

this int Value 

Итак, каждый раз, когда вы объявляете Integer, этот метод расширения будет называться, потому что это именно метод для целого, а не для объекта.

Смежные вопросы