Страницы

Поиск по вопросам

суббота, 20 апреля 2019 г.

Вызов .ToString()

string s = null; Console.WriteLine(Convert.ToString(s));//1 Console.WriteLine(s);//2 Console.WriteLine(s.ToString());//3
Почему в первом случае не выдает NULL reference? Почему во-втором случае не выдает NULL reference? Если я, не ошибаюсь, то в методе Console.WriteLine() ко всем переменным вызывается метод .ToString() не явно. Почему когда явно указываю .ToString() выдает NULL reference? Можно ссылки по данным вопросам или ключевые слова для поиска нужной информации.
Вот il-код программы:
IL_0000: nop IL_0001: ldnull IL_0002: stloc.0 IL_0003: ldloc.0 IL_0004: call string [mscorlib]System.Convert::ToString(string) IL_0009: call void [mscorlib]System.Console::WriteLine(string) IL_000e: nop IL_000f: ldloc.0 IL_0010: call void [mscorlib]System.Console::WriteLine(string) IL_0015: nop IL_0016: ldloc.0 IL_0017: callvirt instance string [mscorlib]System.Object::ToString() IL_001c: call void [mscorlib]System.Console::WriteLine(string) IL_0021: nop IL_0022: ret


Ответ

По поводу вывода null через Console.WriteLine(), MSDN говорит
If value is null, only the line terminator is written to the standard output stream.
То есть Console.WriteLine(null) выводит один лишь перевод строки. Это объясняет пример (2). В этом случае Console.WriteLine согласно документации не имеет права тупо вызывать ToString (тем более что мы вызвали перегрузку со строкой, там конвертация точно не нужна). Для того, чтобы соответствовать документации, функция обязана проверять свой аргумент на null. Это можно увидеть прямо в исходниках текущей версии .NET
if (value==null) { WriteLine(); } else { ...

Далее, согласно документации на Convert.ToString(string s), значение не меняется:
value is returned unchanged.
Поэтому Convert.ToString(s) возвращает null, а уж вывод null работает без проблем, как и в примере (2). Это объясняет пример (1).

Ну и наконец пример (3), вызов s.ToString() есть вызов метода по null-ссылке, который закономерно ведёт к NullReferenceException

Комментариев нет:

Отправить комментарий