C#2.0
-
泛型
-
部分類型
-
匿名方法
-
迭代器
-
可空類型
-
Getter / setter單獨可訪問性
-
方法組轉換(代表)
-
Co- and Contra-variance for delegates
-
靜態類
-
Delegate inference
C#3.0
-
隱式類型局部變量
-
對象和收集初始化器
-
自動實現的屬性
-
匿名類型
-
擴展方法
-
查詢表達式
-
Lambda表達式
-
表達樹
-
部分方法
C#4.0
-
動態綁定
-
命名和可選參數
-
Generic co- and contravariance
-
嵌入式互操作類型(“NoPIA”)
C#5.0
-
異步方法
-
Caller info attributes
C#6.0
-
Compiler-as-a-service(Roslyn)
-
將靜態類型成員導入命名空間
-
異常過濾器
-
在Catch和Finally中使用Await
-
自動屬性初始化器
-
只讀屬性的默認值
-
Expression-bodied members
-
Null-conditional operators(空條件運算符,簡潔檢查)
-
字符串插值
-
nameof operator
-
字典初始化器
C#7.0
-
out變量
-
模式匹配
-
元組
-
解構
-
局部函數
-
數字分隔符
-
二進制文字
-
局部引用和引用返回
-
擴展異步返回類型
-
表達式的構造函數和finalizers
-
Expression bodied getters and setters
-
throw表達式
c#7.0新特性詳解
C#7.0增加許多新功能,重點是數據,代碼簡化和性能上。
Out variables
目前在C#中,使用out參數不像我們想要的那么流暢。在使用out參數調用一個方法之前,首先必須聲明變量來傳遞給它。您也不能使用var
它們來聲明它們,但需要指定完整的類型。
public void PrintCoordinates(Point p) { int x, y; //必須聲明 p.GetCoordinates(out x, out y); WriteLine($"({x}, {y})"); }
在c#7中
public void PrintCoordinates(Point p) { p.GetCoordinates(out int x, out int y); WriteLine($"({x}, {y})"); }
模式匹配
以前版本需要轉化
public static void PrintStars(object o) { if (o is int) Console.WriteLine(Convert.ToInt32(o) + 12); }
在c#7中
public static void PrintStars(object o) { if (o is int i)
Console.WriteLine(i + 12); }
Switch statements with patterns 擴展switch語句使用模式匹配
public static void PrintStars(object o)
{
switch (o)
{
case Print p:
break;
case int a:
break;
case String b when b=="123":
break;
}
}
}
元組(Tuples)
元組依賴於一組基礎類型,不包括在預覽4中。要使功能正常工作,您可以通過NuGet輕松獲取它們:
-
右鍵單擊解決方案資源管理器中的項目,然后選擇“管理NuGet軟件包...”
-
選擇“瀏覽”選項卡,選中“包含預發行”,然后選擇“nuget.org”作為“包源”
-
搜索“System.ValueTuple”並安裝它。
static void Main(string[] args)
{
var tuple = (a: 10, b: "123");
Console.WriteLine($"a:{tuple.a},b:{tuple.b}");
var result1 = GetS();
var result = Get();
Console.WriteLine($"Item1:{result1.Item1},Item2:{result1.Item2},Item3:{result1.Item3}");
Console.WriteLine($"a:{result.a},b:{result.b},c:{result.c}");
Console.ReadLine();
}
static (string, int, DateTime) GetS()
{
return ("abc", 123, DateTime.Now);
}
static (string a, int b, DateTime c) Get()
{
return (a: "abc", b: 123, c: DateTime.Now);
}
部函數
簡單的說,就是在方法里面寫方法然后自己調用。
static void Main(string[] args) { Console.WriteLine($"{Get(123)},{Get("abc")},{Get(null)}"); Console.ReadLine(); } public static string Get(object a) { return GetP(); string GetP() { if (a is int v) return v + ""; if (a is string b) return b; return "ccc"; } }
Literal improvements
C#7.0允許在數字文字中_
作為數字分隔符出現:
var d = 123_456; var x = 0xAB_CD_EF;
你可以把它們放在數字之間,以提高可讀性。它們對價值沒有影響。另外,C#7.0引入了二進制文字,因此您可以直接指定位模式,而不必以心臟知道十六進制符號。
var b = 0b1010_1011_1100_1101_1110_1111;
更多c#7.0的特性
請參考文檔:https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
c#6.0新語言功能詳解
以下新功能在VS 2015及17中實現並可用
字符串格式化
上面的代碼中都有體現。
public void Main()
{
int i = 1;
string s = "id";
Console.WriteLine($"{s}-{i}");
}
字典索引初始化
var numbers = new Dictionary<int, string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };
自動屬性初始化
public class Customer { public string First { get; set; } = "Jane"; public string Last { get; set; } = "Doe"; }
using引用靜態類
If you have a static class, whose members you are using a lot you can now avoid typing the class name everytime by including the class in the using declaration.
using static System.Console; using static System.Math; using static System.DayOfWeek; class Program { static void Main() { WriteLine(Sqrt(3*3 + 4*4)); WriteLine(Friday - Monday); } }
Exception Filters
Exception filters allow you to add additional conditions to exception handlers. We can now write an if a when statement next to a catch block & the catch block will only get executed if the condition returns true. Below is an impractical & silly example to play around with.
public void Main()
{
try
{
throw new Exception("E2");
}
catch(Exception ex) when (ex.Message == "E1")
{
Console.WriteLine("caught E1");
}
catch(Exception ex) when (ex.Message == "E2")
{
Console.WriteLine("caught E2");
}
}
Using await in catch and finally blocks
We can now await functions in catch and finally blocks. This was not allowed prior to C# 6.0
public void Main()
{
BuggyFunctionAsync();
Console.WriteLine("done!");
Thread.Sleep(2000);
}public async void BuggyFunctionAsync()
{
try { throw new Exception(); }
catch
{
Console.WriteLine("entering catch block");
await Task.Delay(1000);
Console.WriteLine("exiting catch block");
}
finally
{
Console.WriteLine("entering finally block");
await Task.Delay(1000);
Console.WriteLine("exiting finally block");
}
}
The nameof Operator
There are times when we need the name of a variable in string form. nameof operator does just that. It takes a variable and converts the variable name to string.
public void Main()
{
Console.WriteLine(nameof(Account));
Console.WriteLine(nameof(Account.AccountNumber));
}class Account
{
public int AccountNumber{get; set;}
}
Null Conditional Operator
if(node==null || node.Children == null)
Console.WriteLine("Invalid Node");
if(node?.Children == null)
Console.WriteLine("Invalid Code");
c#2.0-5.0參考文檔
c#5.0參考文檔
c#4.0參考文檔
連接地址:https://msdn.microsoft.com/en-us/magazine/ff796223.aspx
c#3.0參考文檔
連接地址:https://msdn.microsoft.com/en-us/library/bb308966.aspx
c#2.0參考文檔
連接地址:https://msdn.microsoft.com/en-us/library/7cz8t42e(v=vs.80).aspx