你确实应该学习并使用的 10 个 C# 特性

1) async / await

使用 async / await 模式,能够在执行代码块操做的时候不会阻塞 UI 或者当前的线程。即便该操做被某些执行动做延迟了(好比一个 web 请求),async / await 模式也会继续执行后续的代码。web

更多关于 async / await 模式的内容,请见:https://msdn.microsoft.com/zh-cn/library/hh191443.aspxexpress

2) 对象 / 数组 / 集合的初始值设定项(initializers)

经过使用对象、数组、集合的初始值设定项,能够很容易地建立类、数组和集合的实例:数组

1
2
3
4
5
6
7
8
// 示例类
public  class  Employee {
     public  string  Name { get set ;}
     public  DateTime StartDate { get set ;}
}
 
// 使用初始值设定项建立员工实例
Employee emp =  new  Employee {Name= "John Smith" , StartDate=DateTime.Now()};

上述示例中的代码在单元测试中可能很是有帮助,不过在有些状况下也应该避免使用它,好比应该经过构造函数来进行类的实例化的时候。闭包

更多关于初始值设定项的内容,请见:https://msdn.microsoft.com/zh-cn/library/bb384062.aspxasync

3) Lambda 表达式、谓词委托(predicates)、委托(delegates)和闭包(closures)

这些特性在不少状况下都是很是必要的(好比使用 Linq 的时候),请务必学习在什么时候以及如何使用它们。ide

更多关于 Lambda 表达式、谓词委托、委托和闭包的内容,请见:http://www.codeaddiction.net/articles/13/lambda-expressions-delegates-predicates-and-closures-in-c函数

4) ?? – null 合并运算符(Null coalescing operator)

当表达式左侧不为 null 的时候,?? 运算符返回其左侧的值,不然返回其右侧的值:工具

1
2
3
4
5
6
// 多是 null
var someValue = service.GetValue();
var defaultValue = 23
 
// 若是 someValue 是 null 的话,result 为 23
var result = someValue ?? defaultValue;

?? 运算符能够用于链式操做:单元测试

1
string  anybody = parm1 ?? localDefault ?? globalDefault;

它也能够将可空类型转换为非可空类型:学习

1
var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0);

更多关于 ?? 运算符的内容,请见:https://msdn.microsoft.com/zh-cn/library/ms173224.aspx

5) $”{x}” – 内插字符串(String Interpolation)- C# 6

C# 6 的一个新特性,能够经过更加高效和优雅的方式来进行字符串拼接:

1
2
3
4
5
// 传统方式
var someString = String.Format( "Some data: {0}, some more data: {1}" , someVariable, someOtherVariable);
 
// 新的方式
var someString = $ "Some data: {someVariable}, some more data: {someOtherVariable}" ;

也能够在大括号中写 C# 表达式,这让它变得很是强大。

6) ?. – null 条件运算符(Null-conditional operator) – C# 6

null 条件运算符使用起来以下所示:

1
2
// 若是 customer 或 customer.profile 或 customer.profile.age 为 null 的话,结果都是 null
var currentAge = customer?.profile?.age;

再也不会发生 NullReferenceExceptions 了!

更多关于 ?. 运算符的内容,请见:https://msdn.microsoft.com/zh-cn/library/dn986595.aspx

7) nameof 表达式 – C# 6

新的 nameof 表达式可能看上去没那么重要,不过它确实也有其用武之地。在使用自动重构工具(好比 Resharper)时,你可能会须要经过参数的名字来表示它:

1
2
3
4
5
6
7
8
public  void  PrintUserName(User currentUser)
{
     // 在重命名 currentUser 的时候,重构工具可能会遗漏在文本中的这个变量名
     if (currentUser ==  null )
         _logger.Error( "Argument currentUser is not provided" );
 
     //...
}

如今你能够这样来写:

1
2
3
4
5
6
7
8
public  void  PrintUserName(User currentUser)
{
     // 重构工具不会漏掉这个
     if (currentUser ==  null )
         _logger.Error($ "Argument {nameof(currentUser)} is not provided" );
 
     //...
}

更多关于 nameof 表达式的内容,请见:https://msdn.microsoft.com/zh-cn/library/dn986596.aspx

8) 属性初始值设定项 – C# 6

你能够经过属性初始值设定项,在声明一个属性的时候指定一个初始值:

1
2
3
4
5
public  class  User
{
     public  Guid Id {  get ; } = Guid.NewGuid(); 
     // ...
}

使用属性初始值设定项的一个好处,就是你没必要声明一个 setter 方法,从而使得该属性成为不可变的(immutable)。属性初始值设定项能够和 C# 6 的主构造函数(Primary Constructor)语法配合使用。(译者注:Primary Constructor 语法可让你在定义一个类的同时,在类名以后当即指定一个带参数的构造函数)

9) as / is 运算符

is 运算符用来判断一个实例是不是特定类型的,好比你想看一下类型转换是不是可行的:

1
2
3
4
if  (Person  is  Adult)
{
     //do stuff
}

as 运算符会试图将某个对象转换为某个特定类的实例。若是没法转换的话会返回 null:

1
2
3
4
5
SomeType y = x  as  SomeType;
if  (y !=  null )
{
     //do stuff
}

10) yield 关键字

你能够经过 yield 关键字来返回 IEnumerable 接口的数据项。下面的示例会返回 2 的次方(好比直到 8 次方:二、四、八、1六、3二、6四、12八、256):

1
2
3
4
5
6
7
8
9
public  static  IEnumerable< int > Power( int  number,  int  exponent)
{
     int  result = 1;
     for  ( int  i = 0; i < exponent; i++)
     {
       result = result * number;
       yield  return  result;
     }
}

若是使用得当的话,yield 会变得很是强大。它使得你延迟生成序列中的对象,好比当系统不须要枚举整个集合的时候,能够按需中止。

相关文章
相关标签/搜索