您當前的位置:首頁 > 書法

使用現代化 C# 語法簡化程式碼

作者:由 dotnet程式設計大全 發表于 書法時間:2022-05-07

使用現代化 C# 語法簡化程式碼

Intro

最近幾個版本的 C# 在語法中有很多的變化,有很多語法能夠幫助我們大大簡化程式碼複雜度,使得程式碼更加簡潔,分享幾個我覺得比較實用的可以讓程式碼更加簡潔的語法

Default literal expressions

在 C# 7。1 之後,我們可以使用

default

來代替一個型別的預設值,例如:

publicvoidTest(stringstr=deault){}

stringstr=default;

在之前的版本我們需要顯式指定型別,如

default(string)

,就不需要寫型別了,編譯器會推斷出型別

Target-Typed New Expression

在 C# 9 中,引入了

Target-Typed New Expression

語法,和上面的

default

類似,我們在建立物件的時候不再需要在編譯器可以推斷出型別的地方再寫出型別了,這在有時候會很有用,尤其是在寫一個型別非常複雜的欄位的時候,我們就只需要宣告一次就可以了,可以參考下面的示例:

//target-typednewexpression

//privatestaticreadonlyDictionary>

//Dictionary=newDictionary>();

privatestaticreadonlyDictionary>

Dictionary=new();

//array

ReviewRequest[]requests=

{

new()

{

State=ReviewState。Rejected

},

new(),

new(),

};

Named Tuple

從 C# 7 開始,我們可以使用

Named Tuple

來最佳化 Tuple 的使用,在之前的版本我們只能 Item1, Item2 這樣去使用 Tuple 的 Value,但是這樣很不好理解,尤其是在沒有文件說明的情況下,可能每次都要去返回值的地方看一下究竟每一個元素代表什麼,

Named Tuple

出現了之後就相當於一個強型別的 Tuple,能夠使得程式碼更好理解,tuple 元素的含義一目瞭然,舉個栗子:

(stringAlpha,stringBeta)namedLetters=(“a”,“b”);

Console。WriteLine($“{namedLetters。Alpha},{namedLetters。Beta}”);

(intcode,stringmsg)result=(1,“”);

privatestatic(intcode,stringmsg)NamedTuple()

{

return(0,string。Empty);

}

varresult=NamedTuple();

Console。WriteLine(result。code);

Deconstruct

Named Tuple

同時出現的,我們可以在類中宣告一個

Deconstruct

Constructor

相對應,只是

Constructor

是輸入引數,

Deconstruct

是輸出引數,來看一個示例吧:

publicclassPoint

{

publicPoint(doublex,doubley)

=>(X,Y)=(x,y);

publicdoubleX{get;}

publicdoubleY{get;}

publicvoidDeconstruct(outdoublex,outdoubley)=>

(x,y)=(X,Y);

}

varp=newPoint(3。14,2。71);

(doubleX,doubleY)=p;

上面的示例是官方文件的一個示例,來看一個我們實際在用的一個示例吧:

publicclassIdNameModel

{

publicintId{get;set;}

publicstringName{get;set;}

publicvoidDeconstruct(outintid,outstringname)

{

id=Id;

name=Name;

}

}

多個返回值時,有的資料不關心可以使用 “_” 來表示丟棄返回值,示例如下:

usingSystem;

usingSystem。Collections。Generic;

publicclassExample

{

publicstaticvoidMain()

{

var(_,_,_,pop1,_,pop2)=QueryCityDataForYears(“NewYorkCity”,1960,2010);

Console。WriteLine($“Populationchange,1960to2010:{pop2-pop1:N0}”);

}

privatestatic(string,double,int,int,int,int)QueryCityDataForYears(stringname,intyear1,intyear2)

{

intpopulation1=0,population2=0;

doublearea=0;

if(name==“NewYorkCity”)

{

area=468。48;

if(year1==1960)

{

population1=7781984;

}

if(year2==2010)

{

population2=8175133;

}

return(name,area,year1,population1,year2,population2);

}

return(“”,0,0,0,0,0);

}

}

//Theexampledisplaysthefollowingoutput:

//Populationchange,1960to2010:393,149

Pattern-Matching

模式匹配最早開始於 C# 7。1,最早的形式如:

if(a is string str)

,這是最簡單也是最經典的一個模式匹配,它結合了之前需要兩句話才能完成的功能,可以翻譯成:

varstr=aasstring;

if(str!=null)//。。。

除了

if

,我們在

switch

裡也可以使用模式匹配的

voidSwitchPattern(objectobj0)

{

switch(obj0)

{

casestringstr1:

Console。WriteLine(str1);

break;

caseintnum1:

Console。WriteLine(num1);

break;

}

}

在 C# 9 中引入了邏輯運算子

and

/

or

/

not

使得模式匹配更為強大,來看一個判斷是否是合法的 Base64 字元的一個方法的變化:

C# 9 之前的程式碼:

privatestaticboolIsInvalid(charvalue)

{

varintValue=(int)value;

if(intValue>=48&&intValue<=57)

returnfalse;

if(intValue>=65&&intValue<=90)

returnfalse;

if(intValue>=97&&intValue<=122)

returnfalse;

returnintValue!=43&&intValue!=47;

}

使用 C# 9 增強的模式匹配之後的程式碼:

privatestaticboolIsInvalid(charvalue)

{

varintValue=(int)value;

returnintValueswitch

{

>=48and<=57=>false,

>=65and<=90=>false,

>=97and<=122=>false,

_=>intValue!=43&&intValue!=47

};

}

是不是一下子清晰的很多~~

Switch Expression

Switch Expression 是 C# 8 引入的新特性,C# 9 有結合模式匹配做了進一步的增強,使得其功能更加強大,來看示例吧:

修改前的程式碼是這樣的:

varstate=ReviewState。Rejected;

varstateString=string。Empty;

switch(state)

{

caseReviewState。Rejected:

stateString=“0”;

break;

caseReviewState。Reviewed:

stateString=“1”;

break;

caseReviewState。UnReviewed:

stateString=“-1”;

break;

}

使用 switch expression 之後的程式碼如下:

varstate=ReviewState。Rejected;

varstateString=stateswitch

{

ReviewState。Rejected=>“0”,

ReviewState。Reviewed=>“1”,

ReviewState。UnReviewed=>“-1”,

_=>string。Empty

};

是不是看起來簡潔了很多,還有進一步的增加最佳化,來看下一個示例:

(intcode,stringmsg)result=(0,“”);

varres=resultswitch

{

(0,_)=>“success”,

(-1,_)=>“xx”,

(-2,“”)=>“yy”,

(_,_)=>“error”

};

Console。WriteLine(res);

猜猜不同情況的輸出的結果是什麼樣的,再自己試著跑一下結果看看是不是符合預期吧

Index Range

Index/Range 是 C# 8 引入的一個新特性,主要優化了對元組的操作,可以更方便的做索引和切片操作

之前有過一篇詳細的介紹文章,可以參考:

C# 使用 Index 和 Range 簡化集合操作

我們可以透過

^

(hat) 運算子來反向索引陣列中的物件,可以透過

。。

來建立一個集合的子集合,來看一個簡單的示例:

vararr=Enumerable。Range(1,10)。ToArray();

Console。WriteLine($“lastelement:{arr[^1]}”);

varsubArray=Enumerable。Range(1,3)。ToArray();

Console。WriteLine(arr[。。3]。SequenceEqual(subArray)?“StartWith”:“No”);

Record

Record 是 C# 9 引入的新特性,record 是一個特殊的類,編譯器會幫助我們做很多事情,會自動實現一套基於值的比較,而且可以很方便實現物件複製的功能,詳細介紹可以參考之前的 record 介紹文章

C# 9 新特性 — record 解讀

,可以看下面這個簡單的示例:

publicabstractrecordPerson(stringFirstName,stringLastName);

publicrecordTeacher(stringFirstName,stringLastName,intGrade)

:Person(FirstName,LastName);

publicrecordStudent(stringFirstName,stringLastName,intGrade)

:Person(FirstName,LastName);

publicstaticvoidMain()

{

Personteacher=newTeacher(“Nancy”,“Davolio”,3);

Personstudent=newStudent(“Nancy”,“Davolio”,3);

Console。WriteLine(teacher==student);//output:False

Studentstudent2=newStudent(“Nancy”,“Davolio”,3);

Console。WriteLine(student2==student);//output:True

}

Top-Level Statement

Top-Level statement 是 C# 9 支援的新特性,我們可以不寫 Main 方法,直接寫方法體,對於一些比較簡單的小工具,小測試應用來說會比較方便

usingstaticSystem。Console;

WriteLine(“Helloworld”);

More

除了上面這些新特性,你覺得還有哪些比較實用的新特性呢,歡迎留言一起討論哈~

References

https://

docs。microsoft。com/en-u

s/dotnet/csharp/whats-new/csharp-9

https://

docs。microsoft。com/en-u

s/dotnet/csharp/whats-new/csharp-8

https://

docs。microsoft。com/en-u

s/dotnet/csharp/whats-new/csharp-7

https://

github。com/WeihanLi/Sam

plesInPractice/blob/master/CSharp9Sample/CleanCodeSample。cs

技術群:新增小編微信並備註進群

小編微信:mm1552923

公眾號:dotNet程式設計大全

標簽: C#  console  WriteLine  示例  intValue