C # 4.0 и комбинация необязательных параметров и перегрузок дают вам предупреждение о неоднозначности?

StackOverflow https://stackoverflow.com/questions/1211203

Вопрос

Я начал читать раннюю версию книги Джона Скита, в которой есть разделы на C # 4.0, и одна вещь меня поразила. К сожалению, у меня нет Visual Studio 2010, поэтому я решил просто спросить здесь и посмотреть, знает ли кто-нибудь ответ.

Если у меня есть следующий код, смесь существующего кода и нового кода:

public void SomeMethod(Int32 x, Int32 y) { ... }

public void SomeMethod(Int32 x, Int32 y, Int32 z = 0) { ... }

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

Например, что на самом деле будет делать этот кусок кода?

SomeClass sc = new SomeClass();
sc.SomeMethod(15, 23);

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

Это было полезно?

Решение

Он будет скомпилирован без предупреждений и выберет первую перегрузку.

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

Я не верю, что этот конкретный случай сильно отличается от C # 1.0:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 x, Int32 y, params Int32[] z) { }

который работает идентично (с точки зрения разрешения перегрузки).

Последующий ответ: я так не думаю. Боюсь, вам придется вручную указать аргумент по умолчанию в вызове метода. Однако если параметр x или y имеет другое имя, например:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 t, Int32 y, Int32 z = 0) { }

вы можете выбрать вторую перегрузку с помощью:

obj.SomeMethod(t: 10, y: 20);

Другие советы

Это описано в разделе «Разрешение перегрузки». раздел главы.

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

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

// Both invalid
sc.SomeMethod(15, 23, );
sc.SomeMethod(15, 23, z:)

Если, однако, ваши методы использовали разные имена параметров, вы могли бы сделать это тогда:

public void SomeMethod(Int32 x, Int32 y) { ... }
public void SomeMethod(Int32 a, Int32 b, Int32 c = 0) { ... }

sc.SomeMethod(a: 15, b: 23); // Calls second method
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top