1. 自动属性初始化 (Initializers for auto-properties)

1.1 C#6.0 之前的写法

public class FirstExperience
{
private string _stringAutoProp = "自动初始化属性"; public string StringAutoProp
{
get{ return _stringAutoProp; }
set{ _stringAutoProp = value; }
}
}

1.2 C#6.0 中的写法

public class FirstExperience
{
public string StringAutoProp { get; set; } = "自动初始化属性";
}

1.3 反编译效果



从反编译中我们发现多了个私有字段this.<StringAutoProp>k__BackingField;并在默认的构造函数中将“自动初始化属性”赋值给了这个字段,那么可以推断出IL中肯定会有这个匿名字段的定义,让我们再来看看IL中的体现:

用上面的两张图我们可以得出以下结论

其实自动初始化属性就是在CLR中体现就是创建私有的匿名字段,然后在构造函数中为这个匿名属性赋值,而属性的getSet方法其实就是在操作这个匿名属性。

2. 只读属性的初始化(Getter-only auto-properties)

2.1 C#6.0 之前的写法

public FirstExperience(int id)
{
_id = id;
}
private readonly int _id; public int ID
{
get { return _id; }
}

2.2 C#6.0 中的写法

public int ReadonlyProp { get; }

public FirstExperience(int _readonlyProp)
{
ReadonlyProp = _readonlyProp;
}

2.3 反编译效果



从反编译的结果我们看到构造函数中将传进来的_readonlyProp赋值给this.<ReadonlyProp>k__BackingField字段,而属性的get方法操作的就是这个由编译器生成的字段,而在ReadonlyProp属性的get方法中打了CompilerGenerated这个特性标签,这个标签其实就是区分编译器生成的元素与用户生成的元素,关于这个特性请移步到。由此可以推断IL中所做的操作与自动初始化属性一致

3. 用Lambda作为函数体 (Expression bodies on method-like members)

3.1 C# 6.0 之前的写法

 public override string ToString()
{
return string.Format("{0}",StringAutoProp);
}

3.2 C# 6.0 写法

public override string ToString() => string.Format("{0}", StringAutoProp);

在6.0 语法中我们看到可以使用lambda表达式直接作为函数体,那么编译器到底为我们做了什么呢?

3.3 反编译效果

从反编译中我们可以看出编译器编译的时候把lambda函数直接编译成方法体,那么再看看IL的区别了。

从上面两张图中可以看出除了标注堆栈标注刻度不同以外,看不出有什么差别。我也不是太明白这个地方,求园内的大牛解释解释!

4. 空值判断 (Null-conditional operators)

4.1 恶心的写法

if(xxx !=null)
{
xxx.ToString();
}

这种写法相信有非常多的朋友用过,经常为了一个是否为空的问题搞得代码非常难看,

举个栗子:我们需要获取集合或者是字符喘的长度

if(parem!=null)
{
return parem.Length;
}
return null;

这样的写法实在太恶心了,在6.0语法中我们可以这么写

public int? GetListCount(List<int> list)
{
return list?.Count();
}

4.2 实际应用的栗子

在实际应用中,经常会用到委托,而在之前我们需要调用委托时则需要判断委托是否为空如下代码:

public void Test(TestNew test)
{
if (test != null)
{
test.Invoke();
}
}

对于强迫症的我来说这样太恶心了,于是乎利用6.0的语法开始改造

public void Test1(TestNew test)
{
test?.Invoke();
}

4.3 根据上面的栗子进行反编译

从上图反编译效果可以看到两个方法基本没有差别,接下来看看IL中有什么差别:

上图为6.0语法委托调用的IL图,发现核心还是brtrue.s做IF判断决定执行流

5. nameof表达式 (nameof expressions)

5.1 在实际项目的方法中我们经常需要这样去做参数判断

public void MyMethod(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException("name");
}
}

上面代码中的name是我们手写的字符串,在给参数name改名时经常会忘记改下面的字符串name,然而 6.0 解决了这个问题:

public void MyMethod(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}
}

5.2 nameof的反编译

上图中nameof(name)被替换成了字符串name,就如同常量一样。继续来看看IL做了什么:

从IL中我们可以看到它是直接ldstr,既不是反射也不是拿变量的内存值,在实际运用中有时候我们会通过Type来获取他的类名或者是直接写死的但是这样通过反编译后会发现Type.Name在IL中其实是通过反射来获取,而直接写死的方式,在IL中其实就是定义一个变量到堆栈中然后再引用进去。

nameof(name)具有这两种的的有点,灵活而且相对于type和写死的方式性能更高了。

6. 小结

其实6.0中还有很多新的语法糖,在这里就不一一介绍了,等不忙了,我在把其他的新的语法糖写出来

非常感谢您花时间读完这篇文章,如果您觉得此文不错,请点一下“推荐”按钮,您的“推荐”就是对我最大的鼓励以及不懈努力的肯定。
本文版权归作者和博客园所有,来源网址:http://www.cnblogs.com/Wesley-Zen/欢迎各位转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利以及小小的鄙视。

从反编译的角度去观察C#6.0的更多相关文章

  1. Android反编译基础(apktoos)--广工图书馆APK

    更多精彩内容 :http://www.chenchuangfeng.com QQ:375061590 ------------------------------------------------- ...

  2. Android apk反编译基础(apktoos)图文教程

    本文主要介绍了Android apk反编译基础,使用的工具是apktoos,我们将用图文的方式说明apktoos工具的使用方式,你可以参考这个方法反编译其它APK试试看了 很久有写过一个广工图书馆主页 ...

  3. Unity3D避免代码被反编译

    1.Unity编译后最终会将代码编译在dll里面,无论是ios还是Android解开包以后都可以拿到dll,路径在Data/Managed/Assembly-CSharp.dll 2.IOS其实不用做 ...

  4. Java 反编译工具哪家强?对比分析瞧一瞧

    前言 Java 反编译,一听可能觉得高深莫测,其实反编译并不是什么特别高级的操作,Java 对于 Class 字节码文件的生成有着严格的要求,如果你非常熟悉 Java 虚拟机规范,了解 Class 字 ...

  5. android app反编译

    最新在反编译别人的apk,有时候看到别人的app有很炫的效果,就想知道别人是怎么样实现的,顺便自己参考,借鉴一下,下一次如果工作中碰到这个问题就知道怎么实现了.最近恰好放假三天,就研究了一下,一般别人 ...

  6. Eclipse反编译插件: Jodeclipse与JadClipse

    Eclipse反编译插件: Jodeclipse与JadClipse Jodeclipse 是Jode的Eclipse插件,JadClipse是Jad的Eclipse插件,它们都是非常好的反编译插件. ...

  7. Eclipse安装反编译工具JadClipse

    记录一下安装Eclipse的反编译插件JadClipse的过程: 1.首先准备: 1)JadClipse插件,从网站http://sourceforge.net/projects/jadclipse/ ...

  8. Java中String的intern方法,javap&cfr.jar反编译,javap反编译后二进制指令代码详解,Java8常量池的位置

    一个例子 public class TestString{ public static void main(String[] args){ String a = "a"; Stri ...

  9. Android N 7 【 classes.dex】反编译失败:com.googlecode.d2j.DexException: not support version.

    Microsoft Windows [版本 6.1.7601]版权所有 (c) 2009 Microsoft Corporation.保留所有权利. D:\Android反编译工具[全]\2016\d ...

随机推荐

  1. 网站项目后台的目录命名为admin后,网页莫名其妙的变样了

    这是我的第一篇博客文章,与其说是分享经验,倒不如说是求助 最近因为要完成一个课程设计,在拿一个现成的项目过来改,要用到select下拉菜单,可是发觉怎么我的这个下拉菜单怎么变样了 刚开始它是这样的 感 ...

  2. JQuery中常用的 属性选择器

    jQuery中使用$()作为选择符极大提高工作效率以及方便快捷;一些常用属性的选择器由以下几种 1) $('#id') id选择器 2) $('.class') css选择器,class类名 3) $ ...

  3. 3.1,pandas【基本功能】

    一:改变索引 reindex方法对于Series直接索引,对于DataFrame既可以改变行索引,也可以改变列索引,还可以两个一起改变. 1)对于Series In [2]: seri = pd.Se ...

  4. Android-操作栏之图标导航

    想实现图标向上导航功能,步子分两步走: 1.样式上要改变-->图标要变成可点击的按钮,并有一个向左的箭头. 2.功能上要实现-->实现向上导航 首先谈第一步: 对于拥有fragment的a ...

  5. javascript 倒计时跳转.

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. taglib的使用

    使用自定义的taglib可以是我们对页面数据的处理放在后台,不仅使用方便,而且影藏了处理逻辑,也更加的安全. 需要使用到servlet.jar 1.在web-inf下建立taglib.tld文件 &l ...

  7. root用户安装的软件在普通用户不生效

    root安装完成后,有时候需要进入普通用户,修改以下文件才能生效: .在这个文件中添加环境变量 vim ~/.bash_profile .生效 source ~/.bash_profile

  8. 文件操作IO流

    fopen 打开文件或者生成文件 getc 向文件中读取一个字符 putc 向文件中写入一个字符 fgets 向文件中读取字符串 参数可以设置获取多少个字符串 fputs 向文件中写入字符串 不自动添 ...

  9. org/hamcrest/SelfDescribing

    今天在Idea下使用JUtil的时候,运行@Test,报错:org/hamcrest/SelfDescribing 解决办法: (1)换成junit-4.8.jar (2)junit-4.11.jar ...

  10. Codeforces 461B Appleman and Tree

    http://codeforces.com/problemset/problem/461/B 思路:dp,dp[i][0]代表这个联通块没有黑点的方案数,dp[i][1]代表有一个黑点的方案数 转移: ...