C#(012):C# 6.0 新特性(.NET Framework 4.6 与 Visual Studio 2015 )(C # (012): C # 6.0 new features (. Net framework 4.6 and 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)

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

true
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})";
}
————————

C#6.0 was launched in July 2015 Net framework 4.6, which was released later 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)

In previous versions of string As many placeholders as there are parameters in the format, they must be written in order, otherwise an error will be reported.

In the new version, $is used in front of the string to identify the characters behind it. You can use {object} as a placeholder and support intelligent prompts.

Tip: if you want to output {or} symbols, write two, such as $”{{“.

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)

Static methods that can be used to import a single class.

using static System.Math;

You can also use static methods that import classes for classes that have static and instance methods.

using static
using static System.String;

In LINQ query, you can import LINQ mode by importing enumerable or queryable.

using static System.Linq.Enumerable;

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

Check whether the variable is null. If not, execute.

The old grammar is simple but cumbersome.

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

?. And? [operator reduction]

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

?. There is also a great use when triggering events

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

Now it can be rewritten like this

OnChanged?.(this, args);

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

In this way, dictionary or other objects can be initialized by index assignment

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)

If the expression used for the exception filter evaluates to, the catch clause performs normal processing on the exception. If the expression evaluates to, it will be skipped
Clause.

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

example:

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)

The NAMEOF expression evaluates to the name of the symbol. This is a good way to keep the tool running whenever you need the name of a variable, property, or member field.
One of the most common uses of is to provide the name of the symbol that caused the exception.

nameof

When checking method parameters, it is often written as follows:

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

If the name of the parameter is modified one day, the following string is easy to miss and forget to modify

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

9、 Application of lambda expression in attribute and method

1. Use lambda expressions in attributes

Note that the attribute is not ()

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

2. Use lambda expressions on method members

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


static int LambdaFunc(int x, int y) => x*y;

There are many original point class codes:

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);
    }
}

The point class simplified by lambda using attribute initialization and method is as follows:

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})";
}