首页 > 学院 > 开发设计 > 正文

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

2019-11-17 03:18:01
字体:
来源:转载
供稿:网友

关于“.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往往会成为复杂程序效率的瓶颈。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表