C# 语言历史版本特性(C# 1.0到C# 8.0汇总)

历史版本

C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持。微软将C#提交给标准组织ECMA,C# 5.0目前是ECMA发布的最新规范,C# 6.0还是草案阶段,C# 7.1是微软当前提供的最新规范。

这里仅仅列个提纲,由于C# 5.0是具有ECMA标准规范的版本,所以选择C# 5.0作为主要版本学习,并专题学习C# 6.0,7.0版本新特性。

C#语言规范GitHub库参见:https://github.com/dotnet/csharplang

C#语言路线图及开发中的特性参见: 
https://github.com/dotnet/roslyn/blob/master/docs/Language%20Feature%20Status.md

语言版本 发布时间 .NET Framework要求 Visual Studio版本
C# 1.0 2002.1 .NET Framework 1.0 Visual Studio .NET 2002
C# 1.1\1.2 2003.4 .NET Framework 1.1 Visual Studio .NET 2003
C# 2.0 2005.11 .NET Framework 2.0 Visual Studio 2005
C# 3.0 2007.11 .NET Framework 2.0\3.0\3.5 Visual Studio 2008
C# 4.0 2010.4 .NET Framework 4.0 Visual Studio 2010
C# 5.0 2012.8 .NET Framework 4.5 Visual Studio 2012\2013
C# 6.0 2015.7 .NET Framework 4.6 Visual Studio 2015
C# 7.0 2017.3 .NET Framework 4.6.2 Visual Studio 2017
C# 7.1 2017.6 .NET Framework Visual Studio 2017 v15.3预览版
C# 8.0 待发布  .NET Framework 4.7.1  Visual Studio 2017 v15.7

C# 1.0 特性

第1个版本,编程语言最基础的特性。

  • Classes:面向对象特性,支持类类型
  • Structs:结构
  • Interfaces:接口
  • Events:事件
  • Properties:属性,类的成员,提供访问字段的灵活方法
  • Delegates:委托,一种引用类型,表示对具有特定参数列表和返回类型的方法的引用
  • Expressions,Statements,Operators:表达式、语句、操作符
  • Attributes:特性,为程序代码添加元数据或声明性信息,运行时,通过反射可以访问特性信息
  • Literals:字面值(或理解为常量值),区别常量,常量是和变量相对的

C# 2特性 (VS 2005)

  • Generics:泛型
  • Partial types:分部类型,可以将类、结构、接口等类型定义拆分到多个文件中
  • Anonymous methods:匿名方法
  • Iterators:迭代器
  • Nullable types:可以为Null的类型,该类可以是其它值或者null
  • Getter/setter separate accessibility:属性访问控制
  • Method group conversions (delegates):方法组转换,可以将声明委托代表一组方法,隐式调用
  • Co- and Contra-variance for delegates and interfaces:委托、接口的协变和逆变
  • Static classes:静态类
  • Delegate inference:委托推断,允许将方法名直接赋给委托变量

C# 3特性 (VS 2008)

  • Implicitly typed local variables:
  • Object and collection initializers:对象和集合初始化器
  • Auto-Implemented properties:自动属性,自动生成属性方法,声明更简洁
  • Anonymous types:匿名类型
  • Extension methods:扩展方法
  • Query expressions:查询表达式
  • Lambda expression:Lambda表达式
  • Expression trees:表达式树,以树形数据结构表示代码,是一种新数据类型
  • Partial methods:部分方法

C# 4特性 (VS 2010)

  • Dynamic binding:动态绑定
  • Named and optional arguments:命名参数和可选参数
  • Generic co- and contravariance:泛型的协变和逆变
  • Embedded interop types (“NoPIA”):开启嵌入类型信息,增加引用COM组件程序的中立性

C# 5特性 (VS 2012)

  • Asynchronous methods:异步方法
  • Caller info attributes:调用方信息特性,调用时访问调用者的信息

C# 6特征 (VS 2015)

  • Compiler-as-a-service (Roslyn)
  • Import of static type members into namespace:支持仅导入类中的静态成员
  • Exception filters:异常过滤器
  • Await in catch/finally blocks:支持在catch/finally语句块使用await语句
  • Auto property initializers:自动属性初始化
  • Default values for getter-only properties:设置只读属性的默认值
  • Expression-bodied members:支持以表达式为主体的成员方法和只读属性
  • Null propagator (null-conditional operator, succinct null checking):Null条件操作符
  • String interpolation:字符串插值,产生特定格式字符串的新方法
  • nameof operator:nameof操作符,返回方法、属性、变量的名称
  • Dictionary initializer:字典初始化

C# 7 特征 (Visual Studio 2017)

  • Out variables:out变量直接声明,例如可以out in parameter
  • Pattern matching:模式匹配,根据对象类型或者其它属性实现方法派发
  • Tuples:元组
  • Deconstruction:元组解析
  • Discards:没有命名的变量,只是占位,后面代码不需要使用其值
  • Local Functions:局部函数
  • Binary Literals:二进制字面量
  • Digit Separators:数字分隔符
  • Ref returns and locals:引用返回值和局部变量
  • Generalized async return types:async中使用泛型返回类型
  • More expression-bodied members:允许构造器、解析器、属性可以使用表达式作为body
  • Throw expressions:Throw可以在表达式中使用

C# 7.1 特征 (Visual Studio 2017 version 15.3)

  • Async main:在main方法用async方式
  • Default expressions:引入新的字面值default
  • Reference assemblies:
  • Inferred tuple element names:
  • Pattern-matching with generics:

C# 8.0 特征 (Visual Studio 2017 version 15.7)

  • Default Interface Methods 缺省接口实现
  • Nullable reference type NullableReferenceTypes  非空和可控的数据类型
  • Recursive patterns 递归模式
  • Async streams  异步数据流
  • Caller expression attribute 调用方法表达式属性
  • Target-typed new
  • Generic attributes 通用属性
  • Ranges
  • Default in deconstruction
  • Relax ordering of ref and partial modifiers

标签: C#新特性, C#8.0, C#版本与net framework版本对照, C#历史版本

C#5.0版本

像C#4.0版本一样,C#5.0版本中没有太多功能 - 但是其中一个功能非常庞大。

  • 异步/等待
  • CallerInfoAttributes

当C#5.0发布时,它实际上改变了C#开发人员编写异步代码的方式。虽然直到今天仍然有很多困惑,但我在这里向您保证,这比大多数人想象的要简单得多。这是C#的一个重大飞跃 - 它引入了一个语言级别的异步模型,它极大地赋予了开发人员编写外观和感觉同步(或者至少是连续的)的“异步”代码。

异步编程在处理I/O绑定工作负载(如与数据库,网络,文件系统等进行交互)时非常强大。异步编程通过使用非阻塞方法帮助处理吞吐量。这种方法使用了一个透明的异步状态机中的挂点和相应的延续。

同样,如果CPU负载计算的工作量很大,则可能需要考虑异步执行此项工作。这将有助于用户体验,因为UI线程不会被阻塞,而是可以自由地响应其他UI交互。

编者注:这里有一些关于C#异步编程的最佳实践,使用Async Await.

在C#5.0中,当语言添加了两个新的关键字async和await时,异步编程被简化了。这些关键字适用于Task。下表将作为参考:

async-await

Task表示异步操作。操作可以通过Task返回值,也可以通过Task返回void。当您使用async关键字修饰Task返回方法时,它使方法主体可以使用await关键字。当您请求await关键字的返回值时,控制流将返回给调用者,并且在方法的那个点执行暂停。当await的操作完成后,在同一点上恢复执行。部分代码如下!


  1. class IOBoundAsyncExample
  2. {
  3. private const string Url = "http://api.icndb.com/jokes/random?limitTo=[nerdy]";
  4. internal async Task GetJokeAsync()
  5. {
  6. using (var client = new HttpClient())
  7. {
  8. var response = await client.GetStringAsync(Url);
  9. var result = JsonConvert.DeserializeObject(response);
  10. return result.Value.Joke;
  11. }
  12. }
  13. }
  14. public class Result
  15. {
  16. [JsonProperty("type")] public string Type { get; set; }
  17. [JsonProperty("value")] public Value Value { get; set; }
  18. }
  19. public class Value
  20. {
  21. [JsonProperty("id")] public int Id { get; set; }
  22. [JsonProperty("joke")] public string Joke { get; set; }
  23. }

我们用一个名为GetJokeAsync的方法定义一个简单的类。该方法是返回Task,这意味着我们的GetJokeAsync方法最终会给您一个字符串,或者可能出错。

该方法使用async关键字进行修饰,该关键字允许使用等待关键字。我们实例化并使用一个HttpClient对象。然后我们调用GetStringAsync函数,它接受一个字符串url并返回一个Task 。我们等待从GetStringAsync调用返回的Task。

当响应已经准备好时,就会继续发生并控制从我们曾经挂起的位置恢复。然后,我们将JSON反序列化到Result类的实例中,并返回Joke属性。

一些我最喜欢的成果

  • 查克·诺里斯(Chuck Norris)可以用单一的断言来测试整个应用程序。
  • 查克·诺里斯(Chuck Norris)可以编译语法错误。
  • 项目经理永远不会要求查克·诺里斯(Chuck Norris)做出估计。

欢闹随之而来!我们了解了C#5.0的惊人的异步编程模型。

C#6.0版本

C#6.0的推出有很多很大的进步,很难选择我最喜欢的功能。

  • 字典初始化
  • 异常过滤器
  • 在属性里使用Lambda表达式
  • nameof表达式
  • 空值运算符
  • 自动属性初始化
  • 静态导入
  • 字符串嵌入值

我把范围缩小到三个突出特点:空值运算符,字符串嵌入值和nameof表达式。

虽然nameof表达式很棒,我几乎每次都用它来编写代码,但其他两个特性更有影响力。这让我在字符串嵌入值和空值运算符之间做出决定,这是相当困难的。我决定我最喜欢的是字符串嵌入值,这就是为什么。

空值运算符是伟大的,它允许我写较少的详细代码,但它不一定能防止我的代码中的错误。但是,使用字符串嵌入值可以防止运行时错误 - 这是我的书中的一个胜利。

使用$符号启动字符串文字时,将启用C#中的字符串嵌入值语法。这指示C#编译器打算用各种C#变量,逻辑或表达式来插入此字符串。这是手动字符串连接甚至是string.Format方法的一个主要升级。考虑以下:


  1. class Person
  2. {
  3. public string FirstName { get; set; }
  4. public string LastName { get; set; }
  5. public override string ToString()
  6. => string.Format("{0} {1}", FirstName);
  7. }

我们有一个简单的Person类,具有两个名称属性,用于名字和姓氏。我们重写ToString方法并使用string.Format。问题是,编译时,由于开发人员显然希望将姓氏也作为结果字符串的一部分,因此很容易出错,这一点在“{0} {1} ”参数中很明显。同样,开发人员可以很容易地交换名称或正确提供两个名称参数,但混乱的格式文字只包括第一个索引,等等...现在我们可以考虑使用字符串嵌入值。


  1. class Person
  2. {
  3. public string FirstName { get; set; } = "David";
  4. public string LastName { get; set; } = "Pine";
  5. public DateTime DateOfBirth { get; set; } = new DateTime(1984, 7, 7);
  6. public override string ToString()
  7. => $"{FirstName} {LastName} (Born {DateOfBirth:MMMM dd, yyyy})";
  8. }

我冒昧添加DateOfBirth属性和一些默认的属性值。另外,我们现在在我们的ToString方法的覆盖中使用字符串嵌入值。作为一名开发人员,犯上述错误要困难得多。最后,我也可以在插值表达式中进行格式化。注意第三次嵌入值,DateOfBirth是一个DateTime - 因此我们可以使用您已经习惯的所有标准格式。只需使用:运算符来分隔变量和格式。

示例输出

· David Pine (Born July 7, 1984)

编辑注:有关C#6.0新特性的详细内容,请阅读www.dotnetcurry.com/csharp/1042/csharp-6-new-features

C#7.0版本

从所有集成到 C# 7.0的特性中。

  • 更多的函数成员的表达式体
  • 局部函数
  • Out变量
  • 模式匹配
  • 局部变量和引用返回
  • 元组和解构

我结束了模式匹配,元组和Out变量之间的争论。我最终选择了Out变量,这是为什么。

模式匹配但是我真的不经常使用它,至少现在还没有。也许以后我会更多地使用它,但是对于我迄今为止编写的所有c#代码,没有太多地方可以利用它。同样,这是一个很棒的功能,我确实看到了它的位置 - 只是在C#7.0中这不是我最喜欢的。

元组也是一个很好的补充。元组是语言的重要组成部分,成为一流的公民是非常棒的。我会说,“写tem1,.Item2,.Item3等...的日子已经过去了,但这并不一定是正确的。反序列化失去了元组的名称,使得这个公共API不那么有价值

我也不喜欢ValueTuple类型是可变的这一事实。我只是不明白设计者的决定。我希望有人能给我解释一下,但感觉有点像疏忽。因此,我得到了选择out变量的特性。

自从C#版本1.0以来,try-parse模式已经在各种值类型中出现了。模式如下:


  1. public boolean TryParse(string value, out DateTime date)
  2. {
  3. // 为了简便起见,我们省略了.....
  4. }

该函数返回一个布尔值,指示给定的字符串值是否能够被解析。如果为true,则将分析的值分配给生成的输出参数date。它的使用如下:


  1. DateTime date;
  2. if (DateTime.TryParse(someDateString, out date))
  3. {
  4. // date现在是解析值
  5. }
  6. else
  7. {
  8. // date是DateTime.MinValue,默认值
  9. }

这种模式是有用的,但有点麻烦。有时,不管解析是否成功,开发人员都会采取相同的操作过程。有时使用默认值是可以的。C#7.0中的out变量使得这个更复杂,不过在我看来不那么复杂。

示例如下:


  1. if (DateTime.TryParse(someDateString, out var date))
  2. {
  3. // date现在是解析值
  4. }
  5. else
  6. {
  7. // date是DateTime.MinValue,默认值
  8. }

现在我们移除了if语句块的外部声明,并把声明作为参数本身的一部分。使用var是合法的,因为类型是已知的。最后,date变量的范围没有改变。它从内联声明泄漏到if块的顶部。

你可能会问自己:“为什么这是他最喜欢的功能之一?”.....这种感觉真的没有什么变化。

但是这改变了一切!

它使我们的C#更具有表现力。每个人都喜欢扩展方法,对 - 请考虑以下几点:


  1. public static class StringExtensions
  2. {
  3. private delegate bool TryParseDelegate(string s, out T result);
  4. private static T To(string value, TryParseDelegate parse)
  5. => parse(value, out T result) ? result : default;
  6. public static int ToInt32(this string value)
  7. => To(value, int.TryParse);
  8. public static DateTime ToDateTime(this string value)
  9. => To(value, DateTime.TryParse);
  10. public static IPAddress ToIPAddress(this string value)
  11. => To(value, IPAddress.TryParse);
  12. public static TimeSpan ToTimeSpan(this string value)
  13. => To(value, TimeSpan.TryParse);
  14. }

这个扩展方法类很简洁,表达能力强。在定义了遵循try-parse模式的私有委托之后,我们可以编写一个泛型复合函数,它需要一个泛型类型的参数、要解析的字符串值和TryParseDelegate。现在我们可以安全地依赖这些扩展方法,考虑以下几点::


  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. var str =
  6. string.Join(
  7. "",
  8. new[] { "James", "Bond", " +7 " }.Select(s => s.ToInt32()));
  9. Console.WriteLine(str); // 打印 "007"
  10. }
  11. }

编辑注:要了解C#7的所有新功能,请查看本教程www.dotnetcurry.com/csharp/1286/csharp-7-new-expected-features

结论

这篇文章对我个人而言颇具挑战性。我喜欢C#的许多特性,因此每次发布只收集一个最喜欢的内容是非常困难的。

每个较新版本的C#都包含了强大而有影响力的功能。C#语言团队以无数的方式进行创新 - 其中之一就是引入点发布。在撰写本文时,C# 7.1和 7.2已正式发货。作为C#开发人员,我们生活在一个激动人心的语言时代!

然而,对我来说,对所有这些特性进行分类是相当有见地的;因为它帮助我们了解了什么是实际的,最影响我的日常发展。一如既往,努力成为一个务实的开发者!并不是语言中所有可用的特性都是当前任务所必需的,但了解什么是可用的,这一点很重要。

当我们期待C#8的建议和原型时,我对C#的未来感到兴奋。它看起来确实很有希望,而且语言正在积极地试图缓解“价值亿万美金的错误”。

欢迎转载,转载请注明翻译原文出处(本文章),原文出处(原博客地址),然后谢谢观看

如果觉得我的翻译对您有帮助,请点击推荐支持:)

C# 6.0+VS2015:win8/win10;空值运算符,字符串嵌入值和nameof表达式。

C# 7.0+VS2018:win10元组和解构.

vs2018(c#8.0):正在开发中。

C# 语言历史版本特性(C# 1.0到C# 8.0汇总相关推荐

  1. C# 语言历史版本特性(C# 1.0到C# 8.0汇总)

    历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持.微软将C#提交给标准组织ECMA,C# 5.0目前是ECM ...

  2. 从头来之【iOS及历史版本特性介绍】

    iOS是apple公司的移动操作系统,在iPhone,iPad,iPod中应用,该名最初为Cisco的网络设备操作系统,后授权于Apple公司使用.下面介绍历史版本的特性. iOS1 最大特性是具有其 ...

  3. iOS及历史版本特性介绍

    iOS是apple公司的移动操作系统,在iPhone,iPad,iPod中应用,该名最初为Cisco的网络设备操作系统,后授权于Apple公司使用.下面介绍历史版本的特性. iOS1 最大特性是具有其 ...

  4. 【Redis】Redis4.0、5.0、6.0版本特性整理

    文章目录 Redis版本特性 Redis 4 模块系统 PSYNC 2.0 缓存驱逐策略优化 Lazy Free 交换数据库 混合持久化 内存命令 兼容 NAT 和 Docker Active Def ...

  5. Android从1.0到11版本特性

    目录 API对照表 各版本特性 Android的起源: Android 1.0(API 1-4 ) Android 2.0(API 5-10 ) Android 3.0 (API 11-13 ) An ...

  6. git的历史版本拉分支、回撤revert、回退reset

    一.历史版本拉分支 假如我们要从3.0回退到1.0版本拉分支修改,那么在log找到1.0提交记录右键选择checkout,点击checkout之后当前工作区即回退到该提交的历史版本中. 然后,我们对1 ...

  7. 模拟量无线采集传输,模拟量模块,0~5v,0-10V,0~20ma,4-20ma

    ZKA-XX-WIFI 使 用 说 明 书 [ ]绝密 [ ]NDA [X]公开 版本历史 版本 修订日期 修订人 修订内容 1.0 2014-10-13 综科智控 1.0初版正式发布 1.1 201 ...

  8. iOS1.0到iOS7,iOS七大版本特性回顾

    2013-9-18 15:38:27    出处:搜狐数码    作者:Eskimo    评论(10) | [大 中 小] IT之家(www.ithome.com):iOS1.0到iOS7,iOS七 ...

  9. vs2008中C#3.0语言的新特性

    看了YJingLee's Blog的文章,收获很大,以下文章转自http://www.cnblogs.com/lyj/archive/2008/01/08/1030525.html 总体来说,Visu ...

最新文章

  1. Dubbo基础专题——第一章(带你认识Dubbo)
  2. java object 比较_Java比较两个对象
  3. php网站通过什么联网,PHP通过Ajax调用连接百度效果实现检测网站是否联网的功能...
  4. 又是Dropout两次!这次它做到了有监督任务的SOTA
  5. Python 下的 tcp server/client 通信
  6. python数列分段_按范围分段的Python数组
  7. 万字长文梳理:从0开始,步入Service Mesh微服务架构的世界
  8. shell--6、Shell printf 命令
  9. 杭电5256 序列变换(LIS)
  10. PRML 十大经典机器学习算法
  11. python处理excel文档_python处理excel文件
  12. 验证牛顿公式的局部收敛性,并找到对于牛顿公式不收敛(发散)的函数,比较二分法与牛顿公式的收敛速度
  13. 2019年末,10 位院士对 AI 的深度把脉(下)
  14. 编写程序,计算s=1+(1+2)+(1+2+3)+…+(1+2+3+…+n)的值,其中n由键盘输入。
  15. python是猿辅导还是学而思_综合分析:猿辅导和学而思对比选哪个好,我的亲身感受...
  16. linux互信文件权限,Linux如何建立互信
  17. 怎么理解token,tokenize,tokenizer.
  18. goproxy代理软件 v10.3 轻量级高性能代理软件+链式代理+正向代理+反向代理
  19. EAUML日拱一卒-微信小程序实战:位置闹铃 (13)-使用类优化程序结构
  20. AxureRP7.0教程 AxureRP7.0数学函数详解

热门文章

  1. 电路板排针拆除(拔出)方法
  2. DELL EMC T150 服务器在h755上快速 安装 win2016 server
  3. halcon-检测圆弧拟合圆
  4. Windows下载安装Redis
  5. Server2012R2下安装intel 82579v网卡驱动
  6. Android 文件转base64字符串,json文件转对象
  7. js使用基础总结(简单封装,事件,foreach 原生js写法)
  8. Win10左下角搜索栏以及资源管理器搜索栏无法使用(点击没有反应)
  9. 响应式微服务_低风险整体式微服务演进第三部分
  10. 浏览器端使用less.js无法解析less文件