#c_sharp
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
Ответы
Ответ 1
По поводу вывода 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.
Комментариев нет:
Отправить комментарий