C#(99):C# 6.0 新特性(.NET Framework 4.6 与 Visual Studio 2015 )

C#6.0 在 2015 年7月随着.NET Framework 4.6 一同发布,后期发布了.NET Framework 4.6.1,4.6.2。

一、自动属性初始化(Auto-property initializers)

public class Account
{
    public string Name { get; set; } = "summit";
  
    public int Age { get; private set; } = 22;
  
    public IList<int> AgeList { get; set; }= new List<int> { 10, 20, 30, 40, 50 };
}

二、字符串嵌入值(String interpolation)

在之前版本的String.Format中有多少个参数就要写多少个占位符还必须按照顺序,否则就报错。

新版本中在字符串前用$来标识后边的字符可以使用{对象}来作为占位符,而且支持智能提示。

tip:如果想输出{或}符号,写两个即可,如$"{{"。

Console.WriteLine($"年龄: {account.Age}  生日: {account.BirthDay.ToString("yyyy-MM-dd")} ");
string  t2 = $"{account.Age}_ {account.BirthDay.ToString("yyyy-MM-dd")}";
Console.WriteLine($" {(account.Age<=22?"小鲜肉":"老鲜肉")} ");

三、导入静态方法(Using Static)

可用于导入单个类的静态方法。

using static System.Math;

还可以使用 using static 为具有静态和实例方法的类导入类的静态方法。

using static System.String;

在 LINQ 查询中可以通过导入 Enumerable 或 Queryable 来导入 LINQ 模式。

using static System.Linq.Enumerable;

四、空值条件运算符(Null-conditional operators)

检查变量是否为null,如果不为null那就执行。

老的语法,简单却繁琐。

public static Point FromJson(JObject json)
{
    if (json != null &&
        json["X"] != null &&
        json["X"].Type == JTokenType.Integer &&
        json["Y"] != null &&
        json["Y"].Type == JTokenType.Integer
        )
    {
        return new Point((int)json["X"], (int)json["Y"]);
    }
    return null;
}

?.?[运算符化简成

public static Point FromJson(JObject json)
{
    if (json?["X"]?.Type == JTokenType.Integer &&
        json?["Y"]?.Type == JTokenType.Integer
        )
    {
        return new Point((int)json["X"], (int)json["Y"]);
    }
    return null;
}

?.还有一个比较大的用处在触发事件的时候

if (onChanged != null)
{
   onChanged(this, args);
}

现在可以改写成这样

OnChanged?.(this, args);

五、索引初始化集合(Index Initializers)

这种方式可以给字典或其他对象通过索引赋值初始化.

IDictionary<int, string> dict = new Dictionary<int, string>() {[1]="first", [2]="second" } ;
foreach(var dic in dict)
{
    Console.WriteLine($"key: {dic.Key} value:{dic.Value}");
}
//output:
//key: 1 value:first
//key: 2 value:second

六、异常过滤器(Exception filters)

如果用于异常筛选器的表达式计算结果为 true,则 catch 子句将对异常执行正常处理。 如果表达式计算结果为 false,则将跳过 catch 子句。

try { 
  //异常抛出
} 
catch (MyException ex) when ex.Status == MyExceptionStatus.A{
   //do something
}
catch (MyException ex) when ex.Status== MyExceptionStatus.B{
   //do something
}
catch (Exception caught) {
   //do something
}

实例:

public static async Task<string> MakeRequest()
{
    WebRequestHandler webRequestHandler = new WebRequestHandler();
    webRequestHandler.AllowAutoRedirect = false;
    using (HttpClient client = new HttpClient(webRequestHandler))
    {
        var stringTask = client.GetStringAsync("https://docs.microsoft.com/en-us/dotnet/about/");
        try
        {
            var responseText = await stringTask;
            return responseText;
        }
        catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301"))
        {
            return "Site Moved";
        }
    }
}

七、nameof表达式 (nameof expressions)

nameof 表达式的计算结果为符号的名称。 每当需要变量、属性或成员字段的名称时,这是让工具正常运行的好办法。 nameof 的其中一个最常见的用途是提供引起异常的符号的名称。

在对方法参数进行检查时经常这样写:

private static void Add(Account account)
{
     if (account == null)
         throw new ArgumentNullException("account");
}

如果某天参数的名字被修改了,下面的字符串很容易漏掉忘记修改.

private static void Add(Account account)
{
     if (account == null)
         throw new ArgumentNullException(nameof(account));
}

八、在cath和finally语句块里使用await(Await in catch and finally blocks)

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.
}

九、Lambda表达式在属性、方法中应用

1、在属性里使用Lambda表达式

注意属性是没有()的

public string Name => string.Format("姓名: {0}", "summit");

2、在方法成员上使用Lambda表达式

public void Print() => Console.WriteLine(Name);
static int LambdaFunc(int x, int y) => x*y;

原Point类代码较多:

public class Point
{
    public int X { get; set; }

    public int Y { get; set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public double Dist
    {
        get { return Math.Sqrt(X * X + Y * Y); }
    }

    public override string ToString()
    {
        return String.Format("({0}, {1})", X, Y);
    }
}

运用属性初始化和方法Lambda简化后的Point类是这样的:

public class Point
{
    public int X { get; } = 2;
    public int Y { get; set; } = 1;
    public double Dist => Sqrt(X * X + Y * Y);
    public override string ToString() => $"({X}, {Y})";
}

posted on 2019-10-11 11:11  springsnow  阅读(686)  评论(0编辑  收藏  举报

导航