C#语言各个版本特性(一)
一、c#版本中添加的功能:
C#2.0
-
泛型
-
部分类型
-
匿名方法
-
迭代器
-
可空类型
-
Getter / setter单独可访问性
-
方法组转换(代表)
-
Co- and Contra-variance for delegates
-
静态类
-
Delegate inference
C#3.0
-
隐式类型局部变量
-
对象和收集初始化器
-
自动实现的属性
-
匿名类型
-
扩展方法
-
查询表达式
-
Lambda表达式
-
表达树
-
部分方法
C#4.0
-
动态绑定
-
命名和可选参数
-
Generic co- and contravariance
-
嵌入式互操作类型(“NoPIA”)
C#5.0
-
异步方法
-
Caller info attributes
C#6.0
-
Compiler-as-a-service(Roslyn)
-
将静态类型成员导入命名空间
-
异常过滤器
-
在Catch和Finally中使用Await
-
自动属性初始化器
-
只读属性的默认值
-
Expression-bodied members
-
Null-conditional operators(空条件运算符,简洁检查)
-
字符串插值
- nameof operator
-
字典初始化器
C#7.0
-
out变量
-
模式匹配
-
元组
-
解构
-
局部函数
-
数字分隔符
-
二进制文字
-
局部引用和引用返回
-
扩展异步返回类型
-
表达式的构造函数和finalizers
- Expression bodied getters and setters
-
throw表达式
C#7.1
- Async main
-
默认表达式
1.C#1.1代码
1 using System.Collections; 2 using System.ComponentModel; 3 4 namespace Chapter01.CSharp1 5 { 6 [Description("Listing 1.01")] 7 public class Product 8 { 9 string name; 10 public string Name 11 { 12 get { return name; } 13 } 14 15 decimal price; 16 public decimal Price 17 { 18 get { return price; } 19 } 20 21 public Product(string name, decimal price) 22 { 23 this.name = name; 24 this.price = price; 25 } 26 27 public static ArrayList GetSampleProducts() 28 { 29 ArrayList list = new ArrayList(); 30 list.Add(new Product("West Side Story", 9.99m)); 31 list.Add(new Product("Assassins", 14.99m)); 32 list.Add(new Product("Frogs", 13.99m)); 33 list.Add(new Product("Sweeney Todd", 10.99m)); 34 return list; 35 } 36 37 public override string ToString() 38 { 39 return string.Format("{0}: {1}", name, price); 40 } 41 } 42 }
代码局限:
1>.ArrayList没有提供与其内部内容相关的编译时信息,可以添加任何类型数据。
2>.代码中为属性设置了公共的get方法,则意味着要添加对应的set方法也是公共的。
3>.用于创建属性和变量的代码过于复杂,包括一个私有变量和一个公共方法。
2.C#2.0代码
1 using System.Collections.Generic; 2 using System.ComponentModel; 3 4 namespace Chapter01.CSharp2 5 { 6 [Description("Listing 1.02")] 7 public class Product 8 { 9 string name; 10 public string Name 11 { 12 get { return name; } 13 private set { name = value; } 14 } 15 16 decimal price; 17 public decimal Price 18 { 19 get { return price; } 20 private set { price = value; } 21 } 22 23 public Product(string name, decimal price) 24 { 25 Name = name; 26 Price = price; 27 } 28 29 public static List<Product> GetSampleProducts() 30 { 31 List<Product> list = new List<Product>(); 32 list.Add(new Product("West Side Story", 9.99m)); 33 list.Add(new Product("Assassins", 14.99m)); 34 list.Add(new Product("Frogs", 13.99m)); 35 list.Add(new Product("Sweeney Todd", 10.99m)); 36 return list; 37 } 38 39 public override string ToString() 40 { 41 return string.Format("{0}: {1}", name, price); 42 } 43 } 44 }
private set{name=value;}
属性可以有公共的get访问器和私有的或者是受保护的set访问器,这有助于控制属性的设置方式。
List<T>强类型集合,可以告知编译器列表中只能包含制定的泛型,试图将一个不同的类型添加到列表中,会造成编译时错误。
3.C#3.0代码
1 using System.Collections.Generic; 2 using System.ComponentModel; 3 4 namespace Chapter01.CSharp3 5 { 6 [Description("Listing 1.3")] 7 class Product 8 { 9 public string Name { get; private set; } 10 public decimal Price { get; private set; } 11 12 public Product(string name, decimal price) 13 { 14 Name = name; 15 Price = price; 16 } 17 18 Product() 19 { 20 } 21 22 public static List<Product> GetSampleProducts() 23 { 24 return new List<Product> 25 { 26 new Product { Name="West Side Story", Price = 9.99m }, 27 new Product { Name="Assassins", Price=14.99m }, 28 new Product { Name="Frogs", Price=13.99m }, 29 new Product { Name="Sweeney Todd", Price=10.99m} 30 }; 31 } 32 33 public override string ToString() 34 { 35 return string.Format("{0}: {1}", Name, Price); 36 } 37 } 38 }
自动实现的属性和简化的初始化大大的简化了代码。(Lambda表达式特性操作同样简捷)
硬编码列表不同的构建方式,由于没有name和price变量可供访问,我们必须在类中处处使用属性,这增强了一致性。
4.C#4.0代码
1 using System.Collections.Generic; 2 using System.ComponentModel; 3 4 namespace Chapter01.CSharp4 5 { 6 [Description("Listing 1.04 (and more)")] 7 public class Product 8 { 9 readonly string name; 10 public string Name { get { return name; } } 11 12 decimal? price; 13 public decimal? Price { get { return price; } } 14 15 public Product(string name, decimal? price = null) 16 { 17 this.name = name; 18 this.price = price; 19 } 20 21 public static List<Product> GetSampleProducts() 22 { 23 List<Product> list = new List<Product>(); 24 list.Add(new Product(name: "West Side Story", price: 9.99m)); 25 list.Add(new Product(name: "Assassins", price: 14.99m)); 26 list.Add(new Product(name: "Frogs", price: 13.99m)); 27 list.Add(new Product(name: "Sweeney Todd", price: 10.99m)); 28 list.Add(new Product(name: "Unpriced")); 29 return list; 30 } 31 32 public override string ToString() 33 { 34 return string.Format("{0}: {1}", name, price); 35 } 36 } 37 }
1>.构造函数包含多个参数时,全部使用命名参数,将不再需要记住或查找形参在所调用方法的形参列表中的顺序。
new Product(price: 9.99m,name: "West Side Story")位置相反也可以构造成功。
2>命名实参与位置实参混合时,要么命名实参位于所有位置实参后面,要么部分位置实参要处于正确的形参列表中位置。
概念:命名实参和可选实参。 通过命名实参,你可以为特定形参指定实参,方法是将实参与该形参的名称关联,而不是与形参在形参列表中的位置关联。 通过可选参数,你可以为某些形参省略实参
注意:命名实参、位置实参、可选实参的区别。
总结:
→C#1,只读属性弱类型集合
→C#2,私有属性赋值方法强类型集合
→C#3,自动实现的属性,增强的集合和对象初始化
→C#4,用命名实参更清晰地调用构造函数和方法。
推荐阅读