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往往会成为复杂程序效率的瓶颈。
新闻热点
疑难解答