Почему компилятор разрешает Convert.ToString() присваиваться целому числу?

Я случайно наткнулся на что-то похожее на следующее в моем коде, он компилирует штраф, но затем явно бомбы во время выполнения:

dynamic fiftySixDynamic = 56;
int fiftySixInt = System.Convert.ToString(fiftySixDynamic);

Каждая перегрузка Convert.ToString() возвращает строку, поэтому, конечно, это не должно компилироваться? Что здесь происходит?

Ответ 1

Вы используете dynamic для ввода в Convert.ToString. Поскольку вход dynamic, привязка метода и проверка типов откладываются до времени выполнения, поэтому компилятор не видит, что единственным возможным типом возврата является string. Компилятор в основном останавливает всю привязку и проверку типов в этой точке.

Даже если вы вызвали fiftySixInt = fiftySixDynamic.ToString(), у которого не может быть перегрузки, которая возвращает int, вы не получите предупреждения от компилятора.

Один из способов избежать ошибок во время компиляции еще не позволяет динамическому поведению - отбрасывать возврат:

int fiftySixInt = (string)System.Convert.ToString(fiftySixDynamic);

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