在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往往会成为复杂程序效率的瓶颈。