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

接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点

叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲。

 

一:字符串嵌入值

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

class Bird
    {
        private string Name = "swallow";

        public void Fly()
        {
            var result = string.Format("hello {0}", Name);
        }
    }

  这个Format有一个不好的地方就是,如果占位符太多,就特别容易搞错,如果你少了一个参数,代码就会报错。

 

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

 

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

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

class Bird
    {
        private string Name = "swallow";

        public void Fly()
        {
            //var result = string.Format("hello {0}{1}", Name);

            var result = "\{"hello"}:\{Name}";

            Console.WriteLine(result);
        }
    }

 

然后就迫不及待的去看看底层怎么玩的,其实在下面的IL图中可以看到,在底层最终还是调用了String.Format方法来实现的。

 

 

二:using静态类

  这种写法看起来有点不伦不类的,乍一看也没有什么用处,不过可以告诉我们一个原理,就是不管你上层怎么变,编译器还是一样使用

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

 

三:空值判断

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

class Bird
    {
        public void Fly(string name)
        {
            var result = name?.Length;
        }
    }

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

 

其实仔细看IL代码之后,觉得一切还是那么的熟悉,重点就是这个brtrue.s。它的状态也决定了两条执行流,不过在IL上面也看到了V_1这个编译

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

class Bird
    {
        public void Fly(string name)
        {
            int? r;

            if (name == null)
            {
                int? V_1 = new Nullable<int>();

                r = V_1;
            }
            else
            {
                r = new Nullable<int>(name.Length);
            }
        }
    }

 

四:nameof表达式

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

传递下去,然后做些后期处理,但是在以前我们只能这么做,要么用反射,要么写死。

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            //第一种:使用反射
            var ilog = new LoggerManager(typeof(Program));

            //第二种:写死
            ilog = new LoggerManager("Program");

            Console.WriteLine("world");
        }
    }

    class LoggerManager
    {
        /// <summary>
        /// 构造函数记录下类名
        /// </summary>
        /// <param name="type"></param>
        public LoggerManager(Type type)
        {
            //todo
            Console.WriteLine(type.Name);
        }
        public LoggerManager(string className)
        {
            //todo
            Console.WriteLine(className);
        }
    }
}

 

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

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

看到IL后,反正我是鸡动了。。。nameof具有上面两者的优点,既灵活,性能又高。。。。不错不错,赞一下。

时间: 2024-12-22 02:53:08

看看C# 6.0中那些语法糖都干了些什么(中篇)的相关文章

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

今天没事,就下了个vs2015 preview,前段时间园子里面也在热炒这些新的语法糖,这里我们就来看看到底都会生成些什么样的IL?   一:自动初始化属性      确实这个比之前的版本简化了一下,不过你肯定很好奇,到底编译器给我们做了哪些东西呢? 1 class Student 2 { 3 public string Name { get; set; } = "ctrip"; 4 }   从这张图中可以看到,在ctor中<Name>k__backingfield=&qu

Objective-C中的语法糖

写这篇博客源于一个疑问:"WoK~, 这也行?!".刚接触OC不久,今天做深浅拷贝的测试,无意中把获取NSArray的值写成了用下标获取的方式.当时把注意力放在了深浅拷贝的内存地址分析上了,就没太在意,测试做完啦,在回顾的时候发现数组是用下标的方式获取的! 于是就有了个疑问,在OC中这样写也行?不是NSArray中有一个方法叫做objectAtIndex来专门获取数组的元素嘛,嗯~用下标也行?此时心里窃喜,可以简化一下数组访问元素的方式了,又可以偷懒啦!!为了更好的偷懒,于是去百度上G

语法糖(Syntactic sugar)

语法糖(Syntactic sugar),是由Peter J. Landin(和图灵一样的天才人物,是他最先发现了Lambda演算,由此而创立了函数式编程)创造的一个词语,它意指那些没有给计算机语言添加新功能,而只是对人类来说更"甜蜜"的语法.语法糖往往给程序员提供了更实用的编码方式,有益于更好的编码风格,更易读.不过其并没有给语言添加什么新东西.   也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用.通常来说,使用语法糖能够增加程序的可

c#中IEnumerable简单实现及 yield return 语法糖

c#中IEnumerable简介及简单实现 IEnumerable这个接口在MSDN上是这么说的,它是一个公开枚举数,该枚举数支持在非泛型集合上进行简单的迭代.换句话说,对于所有数组的遍历,都来自IEnumerable,那么我们就可以利用这个特性,来定义一个能够遍历字符串的通用方法. 下面先贴出code.  代码如下 复制代码 using System;using System.Collections.Generic;using System.Linq;using System.Text;usi

Vue2.0中v-for迭代语法变化(key、index)

今天,在写关于Vue2.0的代码中发现 $key这个值并不能渲染成功,问题如下: 结果这个对象的key值并不能够显示: 后来查阅了文档才知道,这是因为在Vue2.0中,v-for迭代语法已经发生了变化: 丢弃了: 新数组语法 value in arr (value, index) in arr 新对象语法 value in obj (value, key) in obj (value, key, index) in obj 解决后:

Java语法糖之foreach

  语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用了.这些语法糖虽然不会提供实质性的功能改进,但是它们或能提高性能.或能提升语法的严谨性.或能减少编码出错的机会.Java提供给了用户大量的语法糖,比如泛型.自动装箱.自动拆箱.foreach循环.变长参数.内部类.枚举类.断言(assert)等.   本篇主要是讲解foreach,foreach的语法经过

C#语法糖(Csharp Syntactic sugar)大汇总_C#教程

1. 经过简化的Property 早些时候我们这样声明Property 复制代码 代码如下: private string _myName; public string MyName { get { return _myName; } set { _myName = value; } } 千篇一律的这样声明,没有多大意义,于是C#的设计人员将这个千篇一律的工作交给了编译器帮我们做了,我们现在可以这样声明 复制代码 代码如下: public string MyName { get; set; }

c#2.0中新增的两个压缩类

压缩 .NET Framework 2.0 中新增的两个压缩类 System.IO.Compression 命名空间   注意:此命名空间在 .NET Framework 2.0 版中是新增的. System.IO.Compression 命名空间包含提供基本的流压缩和解压缩服务的类. (downmoon原作)  类                               说明  DeflateStream         提供用于使用 Deflate 算法压缩和解压缩流的方法和属性.  G

c#2.0中新增的两个压缩类(downmoon原创)

压缩|原创 .NET Framework 2.0 中新增的两个压缩类 System.IO.Compression 命名空间   注意:此命名空间在 .NET Framework 2.0 版中是新增的. System.IO.Compression 命名空间包含提供基本的流压缩和解压缩服务的类. (downmoon原作)  类                               说明  DeflateStream         提供用于使用 Deflate 算法压缩和解压缩流的方法和属性.