看看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具有上面两者的优点,既灵活,性能又高。。。。不错不错,赞一下。

相关文章
|
6月前
|
程序员 C# 开发框架
深入解析C#中的语法糖
本文将详细探讨C#编程语言中的“语法糖”概念,解释其含义、作用以及在日常编程实践中的常见例子。通过本文,读者将能够更深入地理解C#语言的灵活性和便捷性,并学会如何有效利用语法糖提高代码的可读性和开发效率。
|
XML SQL 开发框架
C#十种语法糖
C#十种语法糖
136 0
C#十种语法糖
lock关键字只不过是C#提供的语法糖
lock关键字只不过是C#提供的语法糖, 最终使用的还是Monitor类. Monitor类的Enter方法要求传入的参数不为null, 否则会有ArgumentNullException exception.
|
8天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
21 3