• 看看C# 6.0中那些语法糖都干了些什么(中篇)


    一:字符串嵌入值

      我想String.Format方法就是化成灰大家都认识,比方以下代码:

    复制代码
    1     class Bird
    2     {
    3         private string Name = "swallow";
    4 
    5         public void Fly()
    6         {
    7             var result = string.Format("hello {0}", Name);
    8         }
    9     }
    复制代码

      这个Format有一个不好的地方就是。假设占位符太多,就特别easy搞错,假设你少了一个參数,代码就会报错。

     

    接下来跟趟顺风车。去看看string.Format底层代码,还是蛮吃惊的发现。事实上底层只是调用的就是StirngBuilder.AppendFormat方法。

     

    由于easy报错。所以为了保险起见就用字符串拼接的方式来实现,可是我也知道字符串拼接是耗时的一种操作,写个StringBuilder又嫌麻烦,

    还好C#6.0中提供了一种新奇玩法,先看代码:

    复制代码
     1     class Bird
     2     {
     3         private string Name = "swallow";
     4 
     5         public void Fly()
     6         {
     7             //var result = string.Format("hello {0}{1}", Name);
     8 
     9             var result = "{"hello"}:{Name}";
    10 
    11             Console.WriteLine(result);
    12         }
    13     }
    复制代码

     

    然后就迫不及待的去看看底层怎么玩的。事实上在以下的IL图中能够看到。在底层终于还是调用了String.Format方法来实现的。

     

     

    二:using静态类

      这样的写法看起来有点不伦不类的,乍一看也没有什么用处,只是能够告诉我们一个原理。就是无论你上层怎么变。编译器还是一样使用

    全命名,这就叫万变不离其宗吧。

     

    三:空值推断

      先还是来看看这样的玩法的真容。

    复制代码
    1     class Bird
    2     {
    3         public void Fly(string name)
    4         {
    5             var result = name?.Length;
    6         }
    7     }
    复制代码

    是不是看着有点眼晕?那就对了,编译器就是这样静静的端着碗看着我们写这些装逼的代码。只是再怎么装逼。也逃只是ILdasm的眼睛。


     

    事实上细致看IL代码之后,认为一切还是那么的熟悉,重点就是这个brtrue.s。

    它的状态也决定了两条运行流,只是在IL上面也看到了V_1这个编译

    器给我们单独定义的一个变量。代码还原例如以下:

    复制代码
     1     class Bird
     2     {
     3         public void Fly(string name)
     4         {
     5             int?

    r; 6 7 if (name == null) 8 { 9 int?

    V_1 = new Nullable<int>(); 10 11 r = V_1; 12 } 13 else 14 { 15 r = new Nullable<int>(name.Length); 16 } 17 } 18 }

    复制代码

     

    四:nameof表达式

      当我知道这个keyword的用途时,我的第一反应就是公司框架里面的LogManager类。当我们new LogManager的时候。会同一时候把当前的类名

    传递下去,然后做些后期处理,可是在曾经我们仅仅能这么做,要么用反射,要么写死。

    复制代码
     1 namespace ConsoleApplication3
     2 {
     3     class Program
     4     {
     5         static void Main(string[] args)
     6         {
     7             //第一种:使用反射
     8             var ilog = new LoggerManager(typeof(Program));
     9 
    10             //另外一种:写死
    11             ilog = new LoggerManager("Program");
    12 
    13             Console.WriteLine("world");
    14         }
    15     }
    16 
    17     class LoggerManager
    18     {
    19         /// <summary>
    20         /// 构造函数记录下类名
    21         /// </summary>
    22         /// <param name="type"></param>
    23         public LoggerManager(Type type)
    24         {
    25             //todo
    26             Console.WriteLine(type.Name);
    27         }
    28         public LoggerManager(string className)
    29         {
    30             //todo
    31             Console.WriteLine(className);
    32         }
    33     }
    34 }
    复制代码

     

    我想大家也能看到,第一种使用了反射,这是须要读取元数据的,性能你懂的。第二个尽管是字符串,你也看到了。是写死的方式,这个时候就

    急需一个加强版。就像以下这样。

    看到IL后,反正我是鸡动了。

    。nameof具有上面两者的长处。既灵活。性能又高。。

    。。

    不错不错。赞一下。

  • 相关阅读:
    C++ Primer Plus(三)
    C++ Primer Plus(二)
    C++ Primer Plus(一)
    C Primer Plus(三)
    C++ 函数重载,函数模板和函数模板重载,选择哪一个?
    Spring IoC 公共注解详解
    Spring IoC @Autowired 注解详解
    Spring IoC 容器的扩展
    Spring IoC bean 的初始化
    Spring IoC 属性赋值阶段
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6953688.html
Copyright © 2020-2023  润新知