Это больше "интересно, почему", чем конкретная проблема, но посмотрите на следующий код
static void Main(string[] args)
{
int val = 10;
Console.WriteLine("val is {0}", val); // (1)
Console.WriteLine("val is {0}", val.ToString()); //(2)
}
В случае (1) выводится следующий IL
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: stloc.0
IL_0004: ldstr "val is {0}"
IL_0009: ldloc.0
IL_000a: box [mscorlib]System.Int32
IL_000f: call void [mscorlib]System.Console::WriteLine(string,
object)
В случае (2), когда я явно вызываю метод toString, я получаю
IL_0014: nop
IL_0015: ldstr "val is {0}"
IL_001a: ldloca.s val
IL_001c: call instance string [mscorlib]System.Int32::ToString()
IL_0021: call void [mscorlib]System.Console::WriteLine(string,
object)
Итак, в случае (1), хотя int переопределяет toString, тип значения помещается в бокс и вызывается метод toString, который предположительно затем вызывает переопределение vtable
Таким образом, результат будет точно таким же, но явный toString избегает операции бокса
Кто-нибудь знает, почему?
= Edit =
ОК, чтобы быть ясным, что меня смущает, что я начинаю с предположения, что хотя int происходит из System.ValueType, который, в свою очередь, происходит из System.Object, потому что он содержит toString, GetHashCode и т.д.
Таким образом, в моем наивном представлении (возможно, из С++), если я переопределяю метод, полученный из System.Object, тогда нет необходимости бросать в System.Object(и, следовательно, вводить тип значения), потому что существует метод overriden, и компилятор будет автоматически укажите запись vtable для типа.
Я также предполагаю, что вызов Console.WriteLine() неявно вызывает int.toString, поэтому, возможно, там, где я ошибаюсь. Надеюсь, что имеет смысл
ОК - все отсортировано. Спасибо всем за то, что вы меня прямо посадили. Все, что я сделал с плохим предположением о том, что Console.WriteLine выполнял неявное преобразование строк. Не спрашивайте меня, почему я думал, что это кажется ослепительно очевидным, как это неправильно сейчас:)