关于“.WriteLine()是否需要这么多重载”的笔记

在Stack Overflow上看到一个较热门的问题,作笔记于此。
Console.WriteLine()有以下如此多的重载:
1 public static void WriteLine(string format, params object[] arg);

2 public static void WriteLine(string format, object arg0);

3 public static void WriteLine(string format, object arg0, object arg1);

4 public static void WriteLine(string format, object arg0, object arg1, object arg2);

5 public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3);
第一个重载能够替代后面的所有重载,为什么还需要后面的重载呢?
JaredPar给出了相关解答:
1.  params参数无法在间接方法绑定中自由的使用,如以下代码:
delegate void E(string format, object o1);

E e = Console.WriteLine;

如在之后按params重载的思路,使用e("{0}, {1}", "a", "b")将无法编译通过。对于指定参数的委托,如需要使用到WriteLine,非params的重载是应该存在的;

2.  并非所有的CLI都支持params的语法;

3.  从性能的角度来说,每次调用public static void WriteLine(string format, params object[] arg),都将分配托管堆空间用于存储对象,哪怕是如下代码:

     

static void Main(string[] args)

{

       DemoFunc("a", "b", "c");

       DemoFunc("a", "b", "c");

}



public static void DemoFunc(params string[] val)

{

}
.method private hidebysig static void  Main(string[] args) cil managed

{

  .entrypoint

  // 代码大小       78 (0x4e)

  .maxstack  3

  .locals init ([0] string[] CS$0$0000)

  IL_0000:  nop

  IL_0001:  ldc.i4.3

  IL_0002:  newarr     [mscorlib]System.String

  IL_0007:  stloc.0

  IL_0008:  ldloc.0

  IL_0009:  ldc.i4.0

  IL_000a:  ldstr      "a"

  IL_000f:  stelem.ref

  IL_0010:  ldloc.0

  IL_0011:  ldc.i4.1

  IL_0012:  ldstr      "b"

  IL_0017:  stelem.ref

  IL_0018:  ldloc.0

  IL_0019:  ldc.i4.2

  IL_001a:  ldstr      "c"

  IL_001f:  stelem.ref

  IL_0020:  ldloc.0

  IL_0021:  call       void ConsoleApplicationDemo2.Program::DemoFunc(string[])

  IL_0026:  nop

  IL_0027:  ldc.i4.3

  IL_0028:  newarr     [mscorlib]System.String

  IL_002d:  stloc.0

  IL_002e:  ldloc.0

  IL_002f:  ldc.i4.0

  IL_0030:  ldstr      "a"

  IL_0035:  stelem.ref

  IL_0036:  ldloc.0

  IL_0037:  ldc.i4.1

  IL_0038:  ldstr      "b"

  IL_003d:  stelem.ref

  IL_003e:  ldloc.0

  IL_003f:  ldc.i4.2

  IL_0040:  ldstr      "c"

  IL_0045:  stelem.ref

  IL_0046:  ldloc.0

  IL_0047:  call       void ConsoleApplicationDemo2.Program::DemoFunc(string[])

  IL_004c:  nop

  IL_004d:  ret

} // end of method Program::Main
从IL中可以看出,.NET都会重复分配托管堆空间。在此,由于程序较为简单, 对于GC的压力较小,但当程序趋于复杂时,过多的分配托管堆空间对GC的压力是很大的,而GC往往会成为复杂程序效率的瓶颈。

你可能感兴趣的:(write)