Почему вызовы C# для перегруженных методов различаются для разных значений одного и того же типа?

У меня есть одно сомнение относительно перегрузки метода С# и разрешения вызовов.

Предположим, у меня есть следующий код С#:

enum MyEnum { Value1, Value2 }

public void test() {
    method(0); // this calls method(MyEnum)
    method(1); // this calls method(object)
}

public void method(object o) {
}

public void method(MyEnum e) {
}

Обратите внимание, что я знаю, как заставить его работать, но я хотел бы знать, почему для одного значения int (0) он вызывает один метод, а для другого (1) вызывает другой. Звучит неловко, так как оба значения имеют один и тот же тип (int), но они «связаны» для разных методов.


person Fabio Veronez    schedule 25.03.2010    source источник
comment
К этому оператору также относится MyEnum e = 0; Но вы получите ошибку компилятора (требуется явное преобразование), если напишите это MyEnum e = 1;   -  person RockWorld    schedule 25.03.2010
comment
Дубликат заголовка stackoverflow.com/questions/1633168/   -  person Binary Worrier    schedule 25.03.2010


Ответы (3)


Литерал 0 неявно преобразуется в любой тип enum, который ближе соответствует типу object. Спецификация.

См., например, эти блог сообщения.

person SLaks    schedule 25.03.2010
comment
0 неявно преобразуется в любой тип перечисления, а 1 — нет!? - person Galilyou; 25.03.2010
comment
@Galilyou: цитата из Спецификации языка C# (раздел 1.10): Чтобы значение по умолчанию для типа перечисления было легко доступно, литерал 0 неявно преобразуется в любой тип перечисления. - person Fredrik Mörk; 25.03.2010

я точно позвоню

public void method(MyEnum e) {
}

правильно вам нужно передать MyEnum.Value1 или MyEnum.Value2. Enum != тип int, поэтому вы должны привести int к вашему типу перечисления. Так что (MyEnum)1 или (MyEnum)0 будут работать правильно.

В вашем случае 0 был неявно приведен к вашему типу перечисления.

person Bryan Denny    schedule 25.03.2010
comment
Хотя ваш ответ (в основном) правильный, ОП спрашивал не об этом. - person Fredrik Mörk; 25.03.2010
comment
Я все еще думаю, что это стоит упомянуть, потому что для удобочитаемости лучше закодировать MyEnum.Value1, чем предполагать, что 0 неявно приведет его к перечислению. Тогда вам не придется беспокоиться о том, что вы попадете в неправильный перегруженный метод. - person Bryan Denny; 25.03.2010
comment
Ты прав; это определенно лучшая практика. Тем не менее, это не ответило на вопрос. - person SLaks; 25.03.2010

Почему C# разрешает неявное преобразование буквального нуля в любое перечисление? — хороший справочник, в котором есть отличный ответ от JaredPar.

person SwDevMan81    schedule 25.03.2010