C# 6 新特性简单总结
1.静态的using声明
静态的using声明允许调用静态方法时不使用类名:
// C# 5
using System;
Console.WriteLine("C# 5");
// C# 6
using static System.Console;
WriteLine("C# 6");
2.表达式体方法
表达式体方法只包含一个可以用Lambda语法编写的语句:
// C# 5
public bool IsSquare(Rectangle rect)
{
return rect.Width == rect.Height;
}
// C# 6
public bool IsSquare(Rectangle rect) => rect.Width == rect.Height;
3.表达式体属性
与表达式体方法类似,只有get存储器的单行属性可以用Lambda语法编写:
// C# 5
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
// C# 6
public string FullName => FirstName + " " + LastName;
4.自动实现的属性初始化器
自动实现的属性可以用属性初始化器来初始化:
// C# 5
public class Person
{
public Person()
{
Age = 24;
}
public int Age { get; set; }
}
// C# 6
public class Person
{
public int Age { get; set; } = 24;
}
5.只读的自动属性
// C# 5
private readonly int _bookId;
public BookId
{
get
{
return _bookId;
}
}
// C# 6
private readonly int _bookId;
public BookId { get; }
6.nameof运算符
使用新的nameof运算符,可以访问字段名、属性名、方法名和类型名。这样,在重构时就不会遗漏名称的改变:
// C# 5
public void Method(object o)
{
if(o == null)
{
throw new ArgumentNullException("o");
}
}
// C# 6
public void Method(object o)
{
if(o == null)
{
throw new ArgumentNullException(nameof(o));
}
}
7.空值传播运算符
空值传播运算符简化了空值的检查:
// C# 5
int? age = p ==null?null : p.Age;
// C# 6
int? age = p?.Age;
8.字符串插值
字符串插值删除了对string.Format的调用,它不在字符串中使用编号的格式占位符,占位符可以包含表达式:
// C# 5
public override string ToString()
{
return string.Format("{0},{1}", Title, Publisher);
}
// C# 6
public override string ToString() => $"{Title}{Publisher}";
9.字典初始化
// C# 5
var dic = new Dictionary<int, string>();
dic.Add(3, "three");
dic.Add(7, "seven");
// C# 6
var dic = new Dictionary<int, string>()
{
[3] = "three",
[7] = "seven"
};
10.异常过滤器
异常过滤器允许在捕获异常之前过滤它们:
// C# 5
try
{
//
}
catch (MyException ex)
{
if (ex.ErrorCode != 405) throw;
}
// C# 6
try
{
//
}
catch (MyException ex) when (ex.ErrorCode == 405)
{
//
}
11.
在catch和finally块中使用await
在C#5中引入一对关键字await/async,用来支持新的异步编程模型,使的C#的异步编程模型进一步的简化。在C#5中虽然引入了await/async,但是却有一些限制,比如不能再catch和finally语句块中使用,C#6中将不再受此限制。
结果private static void Main(string[] args)
{
do
{
Log(ConsoleColor.White, "caller method begin", true);
CallerMethod();
Log(ConsoleColor.White, "caller method end");
} while (Console.ReadKey().Key != ConsoleKey.Q);
}
public static async void CallerMethod()
{
try
{
Log(ConsoleColor.Yellow, "try ", true);
throw new Exception();
}
catch (Exception)
{
Log(ConsoleColor.Red, "catch await begin", true);
await AsyncMethod();
Log(ConsoleColor.Red, "catch await end");
}
finally
{
Log(ConsoleColor.Blue, "finally await begin", true);
await AsyncMethod();
Log(ConsoleColor.Blue, "finally await end");
}
}
private static Task AsyncMethod()
{
return Task.Factory.StartNew(() =>
{
Log(ConsoleColor.Green, "async method begin");
Thread.Sleep(1000);
Log(ConsoleColor.Green, "async method end");
});
}
private static void Log(ConsoleColor color, string message, bool newLine = false)
{
if (newLine)
{
Console.WriteLine();
}
Console.ForegroundColor = color;
Console.WriteLine($"{message,-20} : {Thread.CurrentThread.ManagedThreadId}");
}