zoukankan      html  css  js  c++  java
  • 关于“.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往往会成为复杂程序效率的瓶颈。
  • 相关阅读:
    PHP 单例 工厂模式 类的重载 抽象 接口
    上传文件
    ThinkPHP3.2中if标签
    JS闭包特性 运算符 DOM操作
    循环数组 连接数据库 AJAX
    ThinkPHP
    TP框架
    MVC框架
    类的自动加载,静态属性静态方法
    魔术方法__get()和set函数
  • 原文地址:https://www.cnblogs.com/tonychan/p/3597737.html
Copyright © 2011-2022 走看看