通过一个例子感受C# 6.0新特性

微软在Visual Studio 2015中更新C#语言到6.0,添加了很多很好的特性,以使C#语言继续跻身于最优秀语言之行列。下面通过一个例子快速感受一下C# 6.0的新特性,以下程序在VS2015正式版中测试通过。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 namespace CSharp6Research
  8 {
  9     //分数
 10     public class Fraction
 11     {
 12         public int A { get; set; }
 13 
 14         public int B { get; set; } = 1;
 15 
 16         public string Separator { get; } = "/";
 17 
 18         public string SeparatorSpaces { get; } = string.Empty;
 19 
 20         public double Value => (double)A / B;
 21 
 22         public int this[int index] => index == 0 ? A : B;
 23 
 24         public int this[string index] => index == "A" ? A : B;
 25 
 26         public override string ToString() => $"{A}{SeparatorSpaces}{Separator}{SeparatorSpaces}{B}";
 27 
 28         public void Print() => Console.WriteLine(ToString());
 29 
 30         public Fraction()
 31         {
 32 
 33         }
 34 
 35         public Fraction(int a, int b)
 36         {
 37             A = a;
 38             B = b;
 39         }
 40 
 41         public Fraction(int a, int b, string separatorSpaces) : this(a, b)
 42         {
 43             SeparatorSpaces = separatorSpaces;
 44             if (string.IsNullOrEmpty(separatorSpaces))
 45             {
 46                 throw new ArgumentNullException(nameof(separatorSpaces));
 47             }
 48         }
 49 
 50         public static readonly Dictionary<string, Fraction> CommonFractions =
 51             new Dictionary<string, Fraction>
 52             {
 53                 ["zero"] = new Fraction(),
 54                 ["one"] = new Fraction(1, 1),
 55                 ["half"] = new Fraction(1, 2),
 56                 ["quarter"] = new Fraction(1, 4),
 57                 ["infinity"] = new Fraction(1, 0),
 58             };
 59 
 60     }
 61 
 62     public struct FractionStruct
 63     {
 64         public int A { get; }
 65         public int B { get; }
 66         public FractionStruct(int a, int b) { A = a; B = b; }
 67 
 68         public override string ToString() => $"{A}/{B}";
 69 
 70     }
 71 
 72     class Program
 73     {
 74         static void Main(string[] args)
 75         {
 76             foreach (var f in Fraction.CommonFractions)
 77             {
 78                 Console.WriteLine($"{f.Key} : {f.Value.Value}");
 79             }
 80 
 81             var fraction = new Fraction(1, 3, " ");
 82             fraction.Print();
 83 
 84             try
 85             {
 86                 fraction = new Fraction(1, 2, null);
 87             }
 88             catch (ArgumentNullException e) when (e.ParamName == "separatorSpaces")
 89             {
 90                 Console.WriteLine("separatorSpaces can not be null");
 91             }
 92 
 93             Fraction v;
 94             Fraction.CommonFractions.TryGetValue("harf", out v);
 95             v?.Print();
 96             var a = v?.A;
 97             Console.WriteLine(a == null);
 98             var b = v?["B"];
 99             Console.WriteLine(b == null);
100             Console.WriteLine(v?.ToString() == null);
101 
102             Console.WriteLine(new FractionStruct(0, 1).ToString());
103             Console.WriteLine(default(FractionStruct).ToString());
104         }
105 
106     }
107 }

运行结果如下,

zero : 0
one : 1
half : 0.5
quarter : 0.25
infinity : ∞
1 / 3
separatorSpaces can not be null
True
True
True
0/1
0/0

1. Auto-property initializers 自动属性初始化器

public int B { get ; set ; } = 1;

可以直接给自动属性赋值了,不需要写在构造函数中了。

 

2. Getter-only auto-properties 只读自动属性

public string SeparatorSpaces { get; } = string.Empty;

只读自动属性可以直接初始化,或者在构造函数中初始化。

 

3. Expression-bodied members 表达式体成员

public double Value => (double)A / B;

public int this[int index] => index == 0 ? A : B;

public void Print() => Console.WriteLine(ToString());

只读属性,只读索引器和方法都可以使用Lambda表达式作为Body。

 

4. String interpolation 字符串嵌入值

$"{A}{SeparatorSpaces}{Separator}{SeparatorSpaces}{B}";

字符串前加$,大括号中的表达式会在运行时计算值,并嵌入到字符串中。

 

5. nameof operator  nameof 运算符

throw new ArgumentNullException(nameof(separatorSpaces));

nameof会返回变量,参数或成员名。

这个很有用,原来写WPF中的ViewModel层的属性变化通知时,需要写字符串,或者使用MvvmLight等库中的帮助方法,可以传入获取属性的Lambda,但由于是在运行时解析,会有少许性能损失。现在好了,使用nameof运算符,既能保证重构安全和可读性,又能保证性能。

 

6. Dictionary initializer 字典初始化器

new Dictionary< string, Fraction>

{

    ["zero"] = new Fraction (),

    ["one"] = new Fraction (1, 1),

    ["half"] = new Fraction (1, 2),

    ["quarter"] = new Fraction (1, 4),

    [ "infinity"] = new Fraction (1, 0),

};

现在字典可以用一种可读性更好的方法进行初始化,方括号包围的Key等于Value。

 

7. Exception filters 异常过滤器

catch (ArgumentNullException e) when (e.ParamName == "separatorSpaces")

{

    Console.WriteLine("separatorSpaces can not be null");

}

设置进入catch块的条件。

 

8. Null propagation 空传播

v?.A

v?["B"]

v?.ToString()

对象为null时不调用属性,索引器,方法等,表达式返回null,和Swift中的用法相似。

 

9. Await in catch/finally catch和finally块中的await

例子如下,
Resource res = null;
try
{
    res = await Resource.OpenAsync(…); // You could do this.
    …
}
catch (ResourceException e)
{
    await Resource.LogAsync(res, e); // Now you can do this …
}
finally
{
    if (res != null) await res.CloseAsync(); // … and this.
}

posted @ 2015-01-10 11:38  ClockDotNet  阅读(5051)  评论(9编辑  收藏  举报