Вызов перегрузки конструктора, когда обе перегрузки имеют ту же подпись

Библиотека IO была полностью перепроектирована, и новая реализация находится в чистом Python. Пока это - функциональное улучшение, это в настоящее время намного медленнее. Работа надвигается для перезаписи объема новой системы в C. Для получения дополнительной информации см. эти ошибка отчеты .

18
задан Navaneeth K N 18 August 2009 в 11:04
поделиться

4 ответа

Ваш Этот вопрос горячо обсуждался, когда разрабатывались C # 2.0 и система универсальных типов в CLR. Настолько горячо, что "связанная" спецификация C # 2.0, опубликованная AW, на самом деле содержит неправильное правило! Есть четыре возможности:

1) Сделайте незаконным объявление универсального класса, который ВОЗМОЖНО может быть неоднозначным при НЕКОТОРОЙ конструкции. (Это то, что неправильно указано в связанной спецификации.) Таким образом, ваше объявление Foo было бы незаконным.

2) Сделайте незаконным создание универсального класса способом, который создает двусмысленность. объявление Foo было бы законным, создание Foo было бы законным, но создание Foo было бы незаконным.

3 Сделайте все это легальным и используйте приемы разрешения перегрузки, чтобы определить, какая версия лучше - общая или неуниверсальная. (Это то, что на самом деле делает C #.)

4) Сделайте что-нибудь еще, о чем я не подумал.

Правило №1 - плохая идея, потому что оно делает невозможными некоторые очень распространенные и безобидные сценарии. Рассмотрим, например:

class C<T>
{
  public C(T t) { ... } // construct a C that wraps a T
  public C(Stream state) { ... } // construct a C based on some serialized state from disk
}

Вы хотите, чтобы это было незаконным только потому, что C неоднозначно? Фу. Правило №1 - плохая идея, поэтому мы отказались от него.

К сожалению, это не так просто. IIRC правила CLI говорят, что реализации разрешено отклонять как незаконные конструкции, которые действительно вызывают неоднозначность сигнатур. То есть правила CLI похожи на Правило №2, тогда как C # фактически реализует Правило №3. Это означает, что теоретически могут существовать легальные программы на C #, которые переводятся в незаконный код, что очень прискорбно.

Чтобы узнать больше о том, как такого рода неоднозначности делают нашу жизнь несчастной, вот пара статей, которые я написал о тема:

http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx

http://blogs.msdn.com/ericlippert/archive/2006/04/06 / одиозные-неоднозначные-перегрузки-часть-вторая. aspx

19
ответ дан 30 November 2019 в 06:22
поделиться

Дело в том, что у них обоих нет одинаковой сигнатуры - один использует дженерики, а другой нет.

Имея эти методы, вы также можете вызывать их, используя не- int object:

Foo<string> foo = new Foo<string>("Hello World");
0
ответ дан 30 November 2019 в 06:22
поделиться

Нет двусмысленности, потому что компилятор выберет наиболее подходящую перегрузку Foo (...) . Поскольку метод с параметром универсального типа считается менее специфичным, чем соответствующий неуниверсальный метод, Foo (T) поэтому менее специфичен, чем Foo (int) , когда T == интервал . Соответственно, вы вызываете перегрузку Foo (int) .

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

23
ответ дан 30 November 2019 в 06:22
поделиться
9
ответ дан 30 November 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: