自動(dòng)屬性默認(rèn)初始化
使用方法:
public string Name { get; set; } = "Hello World";
編譯器生成代碼:
public class Customer
{
[CompilerGenerated]
private string kBackingField = "<span style="color: #993300;">hello world</span>";
public Customer()
{
this.kBackingField = "hello world";
}
public string Name
{
[CompilerGenerated]
get
{
return this.<Name>k__BackingField;
}
[CompilerGenerated]
set
{
this.<Name>k__BackingField = value;
}
}
}
從生成代碼中可以看出編譯器是在實(shí)例化構(gòu)造函數(shù)時(shí)蜀肘,初始化屬性信息的。
自動(dòng)只讀屬性默認(rèn)初始化
使用方法:
public string Name1 {get;} = "hello world";
編譯器生成代碼:
public class Customer
{
[CompilerGenerated]
private string kBackingField = "hello world";
public Customer()
{
this.kBackingField = "hello world";
}
public string Name
{
[CompilerGenerated]
get
{
return this.<Name>k__BackingField;
}
[CompilerGenerated]
set
{
this.<Name>k__BackingField = value;
}
}
}
從生成的代碼中也可以看到編譯器是在實(shí)例化構(gòu)造函數(shù)時(shí)柒巫,初始化屬性信息的。
表達(dá)式為主體的函數(shù)
使用方法:
Body Get(int x, int y) => new Body(1 + x, 2 + y);
編譯器生成代碼:
private Program.Body Get(int x, int y)
{
return new Program.Body(1+x, 2+y);
}
從生成的代碼中可以看到簡(jiǎn)化了單選方法的編寫蚌吸,省去寫大括號(hào)的功夫类少。
同時(shí)也支持沒(méi)有返回值的寫法:
void OutPut(int x, int y) => Console.WriteLine("hello, world");
也支持異步函數(shù)的編寫:
async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello world"));
表達(dá)式為主體的屬性(賦值)
使用方法:
public string Name2 => "hello world";
編譯器生成代碼如下:
public string Name2
{
get { return "hello world"; }
}
編譯器只生成了個(gè)只讀屬性
靜態(tài)類導(dǎo)入
這個(gè)比較容易理解,就是一次性導(dǎo)入某類型的所有靜態(tài)成員,然后在后面的代碼中直接使用召嘶,比如:
using static System.Console;
class Program
{
static void Main(string[] args}
{
WriteLine("hello world");
}
}
Null 條件運(yùn)算符
使用方法:
Customer cust = new Customer();
if (cust != null)
{
string name = cust.Name;
}
等同于:
Customer cust = new Customer();
string name = cust?.Name;
可以和父晶??組合起來(lái)使用:
if (customer?.Face()?? false)
還可以2個(gè)一起用
int? Length = customer?.Name?.Length;
這個(gè)語(yǔ)法糖目的是在對(duì)象使用前檢查是否為null弄跌,如果對(duì)象為空,則賦值給變量為宿舍尝苇,所以例子中需要一個(gè)可以為空的Int類型铛只,即int?
如果對(duì)象不為空,則調(diào)用對(duì)象的成員取舍糠溜,并賦值給變量
字符串格式化
在下面的例子中淳玩,String.Format 有些不方便的地方是:必須輸入“String.Format", 使用{0}點(diǎn)位符,必須按順序來(lái)格式化非竿,這點(diǎn)比較容易出錯(cuò):
var s = String.Format("{0} is {1} year old", p.Name, p.Age);
新的語(yǔ)法糖可以這么使用:
var s = $"{p.Name} is {p.Age} year old";
比較有趣的是蜕着,新格式方法還支持任何表達(dá)式的直接賦值:
var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";
索引的初始化
使用List時(shí),雖然可以通過(guò)下面的方式書寫红柱,可以編譯通過(guò)承匣,但還是會(huì)拋異常,使用方法:
var numbers = new List<string> { [7] = "seven", [9] ="nine", [13] ="thirteen"};
編譯器生成代碼:
List list = new List();
list[7] = "seven";
list[9] = "nine";
list[13] = "thirteen";
Dictionary 可以執(zhí)行锤悄,因?yàn)槎邇?nèi)部索引機(jī)制不一樣:
var numbers = new Dictionary<int, string> {[7] = "seven",[9] = "nine",[13] = "thirteen";
異常過(guò)濾器 when
使用方法:
try
{
throw new ArgumentException("string error");
}
catch (ArgumentException e) when (myfilter(e))
{
Console.WriteLine(e.Message);
}
static bool myfilter(ArgumentException e)
{
return false;
}
When語(yǔ)法作用是:在進(jìn)入到catch之前韧骗、驗(yàn)證when括號(hào)里myfilter方法返回的bool,如果返回true繼續(xù)運(yùn)行零聚,false不走catch直接拋出異常袍暴。
使用這個(gè)filter可以更好的判斷一個(gè)錯(cuò)誤是繼續(xù)處理還是重新拋出去。按照以前的做法隶症,在catch塊內(nèi)如需再次拋出去政模,需要重新throw出去,這時(shí)的錯(cuò)誤源是捕捉后在拋的蚂会,而不是原先的淋样,有了when語(yǔ)法就可以直接定位到錯(cuò)誤源。
nameof表達(dá)式
有時(shí)候會(huì)需要程序中一些成員的字符串名稱颂龙,比如拋出ArgumentNullException異常的時(shí)候习蓬,想知道ArgumentNullException類型的字符串名稱,這時(shí)候就可以用nameof獲取字符
串“ArgumentNullException”〈肭叮現(xiàn)在做法都是手動(dòng)復(fù)制一下躲叼,但重構(gòu)改名的時(shí)候容易忘記變更字符串,使用nameof就可以避免了企巢。
string name = "";
Console.WriteLine(nameof(name));