String.Concat(Object)的目的而不是String.Concat(String)

Joh*_*Doe 8 .net c# string clr boxing

使用String.Concat(Object)而不是String.Concat(String)在C#中的目的是什么?为什么不使用隐式调用Object.ToString()而不是传递object自己也可能导致拳击发生?

Int32 i = 5;
String s = "i = ";

// Boxing happens, ToString() is called inside
Console.WriteLine(s + i);
// Why compiler doesn't call ToString() implicitly?
Console.WriteLine(s + i.ToString());
Run Code Online (Sandbox Code Playgroud)

给我们以下IL.

.method private hidebysig static void  MyDemo() cil managed
{
    // Code size       47 (0x2f)
    .maxstack  2
    .locals init ([0] int32 i, [1] string s)
    IL_0000:  nop
    IL_0001:  ldc.i4.5
    IL_0002:  stloc.0
    IL_0003:  ldstr      "i = "
    IL_0008:  stloc.1
    IL_0009:  ldloc.1
    IL_000a:  ldloc.0
    IL_000b:  box        [mscorlib]System.Int32
    IL_0010:  call       string [mscorlib]System.String::Concat(object, object)
    IL_0015:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_001a:  nop
    IL_001b:  ldloc.1
    IL_001c:  ldloca.s   i
    IL_001e:  call       instance string [mscorlib]System.Int32::ToString()
    IL_0023:  call       string [mscorlib]System.String::Concat(string, string)
    IL_0028:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_002d:  nop
    IL_002e:  ret
} // end of method Program::MyDemo
Run Code Online (Sandbox Code Playgroud)

Pat*_*man 3

编译器为什么要这样做?不可以。

如果您传入一个对象(在本例中为装箱的int),编译器唯一的可能就是调用string.Concat(object, object). 它无法调用string.Concat(string, string),因为并非两个参数都是 a string,因此符合第二个重载。

相反,如果适用,它会调用string.Concat(object, object)并执行ToString内部操作。

作为开发人员,您非常了解该string.Concat方法的工作原理。编译器不知道最终它全部变成了string.

另外,如果其中一个objects 是,会发生什么null?将会ToString失败,但有异常。这没有道理。只需传入object并让代码处理它即可。

  • @JohnDoe - 分界线在哪里?您是说,对于存在两个重载的*任何*一组重载,其中一个重载在另一个接受“object”参数的同一位置接受“string”参数,它应该始终在对象,因此“object”重载永远不可调用? (2认同)
  • @Damien_The_Un believer我只是感兴趣为什么对象重载会存在,因为任何对象都可以被ToString'ed。如果对象未初始化(NULL),则代码可能存在问题(使用未初始化的变量),因此对象重载 1) 会向程序员隐藏发出空字符串的错误;2) 导致不必要的装箱,从而降低性能和内存使用量。 (2认同)