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

Как система обработки перегрузки метода решает, какой метод вызывать при передаче пустого значения?

Итак, например, у вас есть тип типа:

public class EffectOptions
{
    public EffectOptions ( params object [ ] options ) {}

    public EffectOptions ( IEnumerable<object> options ) {}

    public EffectOptions ( string name ) {}

    public EffectOptions ( object owner ) {}

    public EffectOptions ( int count ) {}

    public EffectOptions ( Point point ) {}

}

Здесь я просто приведу пример с использованием конструкторов, но результат будет таким же, если бы они были неконструкторскими методами для самого типа, правильно?

Итак, когда вы это сделаете:

EffectOptions options = new EffectOptions (null);

какой конструктор будет вызываться, и почему?

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

4b9b3361

Ответ 1

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

Сначала создайте список всех доступных конструкторов.

public EffectOptions ( params object [ ] options )
public EffectOptions ( IEnumerable<object> options ) 
public EffectOptions ( string name )
public EffectOptions ( object owner ) 
public EffectOptions ( int count ) 
public EffectOptions ( Point point )

Затем устраните все неприменимые конструкторы. Применимый конструктор - это тот, где каждый формальный параметр имеет соответствующий аргумент, а аргумент неявно конвертируется в формальный тип параметра. Предполагая, что Точка является типом значения, мы исключаем версии "int" и "Point". Это оставляет

public EffectOptions ( params object[] options )
public EffectOptions ( IEnumerable<object> options ) 
public EffectOptions ( string name )
public EffectOptions ( object owner ) 

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

public EffectOptions ( object[] options )
public EffectOptions ( IEnumerable<object> options ) 
public EffectOptions ( string name )
public EffectOptions ( object owner ) 

Теперь мы должны определить лучших кандидатов. Правила бестселлера сложны, но короткая версия - это более конкретная, чем менее конкретная. Жираф более специфичен, чем млекопитающее, млекопитающее более специфично, чем животное, животное более конкретное, чем объект.

"Объектная" версия менее конкретна, чем все из них, поэтому ее можно устранить. Версия IEnumerable<object> менее специфична, чем версия object[] (вы видите, почему?), Поэтому ее можно также устранить. Это оставляет

public EffectOptions ( object[] options )
public EffectOptions ( string name )

И теперь мы застряли. объект [] не более или менее специфичен, чем строка. Поэтому это дает ошибку неоднозначности.

Это всего лишь краткий эскиз; реальный алгоритм tiebreaking намного сложнее. Но это основы.

Ответ 2

В этом случае компилятор С# не будет выбирать какой-либо конструктор и вместо этого будет ошибкой. Значение null является законным для нескольких доступных конструкторов, и для его выбора недостаточно логики разлома, поэтому она вызывает ошибку.

Логика разрешения перегрузки компилятора С# представляет собой сложный процесс, но короткий (и по своей сути неполный) обзор того, как он работает, выглядит следующим образом

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

Полная информация приведена в разделе 7.4 спецификации языка С#. И я уверен, что Эрик скоро отправится, чтобы дать гораздо более точное описание:)

Ответ 3

В то время как эта статья отмечена VB, я считаю, что функции С# аналогичны. Как заявил Джаред в своем ответе, если он не может выбрать перегрузку, он выдаст ошибку.

http://msdn.microsoft.com/en-us/library/tb18a48w(v=VS.100).aspx