捨棄-未指派的discardable 變數- C# 指南

文章推薦指數: 80 %
投票人數:10人

說明C# 的discard 支援,這是未指派且可捨棄的變數,並說明discard 的使用方式。

跳到主要內容 已不再支援此瀏覽器。

請升級至MicrosoftEdge,以利用最新功能、安全性更新和技術支援。

下載MicrosoftEdge 其他資訊 目錄 結束焦點模式 儲存 編輯 共用 Twitter LinkedIn Facebook 電子郵件 WeChat 目錄 捨棄-c#基本概念 09/27/2021 B o 此頁面有所助益嗎? Pleaserateyourexperience Yes No 還有其他意見反應嗎? 系統會將意見反應傳送給Microsoft:按下[提交]按鈕,您的意見反應將用來改善Microsoft產品和服務。

隱私權原則。

送出 謝謝。

本文內容 從c#7.0開始,c#支援捨棄,也就是在應用程式程式碼中刻意未使用的預留位置變數。

捨棄相當於未指派的變數;它們沒有值。

捨棄會將意圖傳達給編譯器和其他讀取您程式碼的專案:您想要忽略運算式的結果。

您可能想要忽略運算式的結果、元組運算式的一或多個成員、方法的out參數,或模式符合運算式的目標。

因為只有一個捨棄變數,所以該變數甚至可能無法配置儲存區。

捨棄可以減少記憶體配置。

捨棄讓程式碼的意圖更清楚。

他們增強了其可讀性和可維護性。

指定變數為discard的方式是在其名稱中指派底線(_)。

例如,下列方法呼叫會傳回一個元組,其中的第一個和第二個值會被捨棄。

area是先前宣告的變數,設定為所傳回的第三個元件GetCityInformation: (_,_,area)=city.GetCityInformation(cityName); 從c#9.0開始,您可以使用捨棄來指定lambda運算式未使用的輸入參數。

如需詳細資訊,請參閱lambda運算式一文的lambda運算式章節的輸入參數。

當_是有效的捨棄時,嘗試在指派作業中取出其值或使用它時,會產生編譯器錯誤cs0301:「「名稱'_'不存在於目前的內容中」。

此錯誤是因為_未指派值,甚至可能尚未指派儲存位置。

如果它是實際的變數,您就無法捨棄一個以上的值,如先前的範例所示。

元組和物件解構 當您的應用程式程式碼使用某些元組專案但忽略其他元組專案時,捨棄會很有用。

例如,下列方法會傳回QueryCityDataForYears具有城市名稱的元組、其區域、年份、該年度的城市人口、第二年,以及該第二年的城市人口。

此範例會顯示這兩年之間的人口變化。

在元組可用的資料中,我們對城市區碼不感興趣,並在設計階段得知城市名稱及兩個日期。

因此,我們只對元組中所儲存的兩個人口值感興趣,而可以將其餘值視為discard。

var(_,_,_,pop1,_,pop2)=QueryCityDataForYears("NewYorkCity",1960,2010); Console.WriteLine($"Populationchange,1960to2010:{pop2-pop1:N0}"); static(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 如需使用discard解構元組的詳細資訊,請參閱解構元組和其他類型。

類別、結構或介面的Deconstruct方法也可讓您從一個物件擷取及解構一組特定的資料。

當您只想要使用一部分的解構值時,可以使用[捨棄]。

下列範例會將Person物件解構為四個字串(名字、姓氏、城市和州/省),但捨棄姓氏和州/省。

usingSystem; namespaceDiscards { publicclassPerson { publicstringFirstName{get;set;} publicstringMiddleName{get;set;} publicstringLastName{get;set;} publicstringCity{get;set;} publicstringState{get;set;} publicPerson(stringfname,stringmname,stringlname, stringcityName,stringstateName) { FirstName=fname; MiddleName=mname; LastName=lname; City=cityName; State=stateName; } //Returnthefirstandlastname. publicvoidDeconstruct(outstringfname,outstringlname) { fname=FirstName; lname=LastName; } publicvoidDeconstruct(outstringfname,outstringmname,outstringlname) { fname=FirstName; mname=MiddleName; lname=LastName; } publicvoidDeconstruct(outstringfname,outstringlname, outstringcity,outstringstate) { fname=FirstName; lname=LastName; city=City; state=State; } } classExample { publicstaticvoidMain() { varp=newPerson("John","Quincy","Adams","Boston","MA"); //Deconstructthepersonobject. var(fName,_,city,_)=p; Console.WriteLine($"Hello{fName}of{city}!"); //Theexampledisplaysthefollowingoutput: //HelloJohnofBoston! } } } 如需使用discard解構使用者定義型別的詳細資訊,請參閱解構元組和其他類型。

以switch進行的模式比對 捨棄模式可用於搭配switch運算式的模式比對。

每個運算式(包括null)一律符合捨棄模式。

下列範例會定義一個ProvidesFormatInfo方法,此方法會使用switch運算式來判斷物件是否提供IFormatProvider執行,並測試物件是否為null。

它也會使用捨棄模式來處理任何其他類型的非Null物件。

object[]objects={CultureInfo.CurrentCulture, CultureInfo.CurrentCulture.DateTimeFormat, CultureInfo.CurrentCulture.NumberFormat, newArgumentException(),null}; foreach(varobjinobjects) ProvidesFormatInfo(obj); staticvoidProvidesFormatInfo(objectobj)=> Console.WriteLine(objswitch { IFormatProviderfmt=>$"{fmt.GetType()}object", null=>"Anullobjectreference:ItsusecouldresultinaNullReferenceException", _=>"Someobjecttypewithoutformatinformation" }); //Theexampledisplaysthefollowingoutput: //System.Globalization.CultureInfoobject //System.Globalization.DateTimeFormatInfoobject //System.Globalization.NumberFormatInfoobject //Someobjecttypewithoutformatinformation //Anullobjectreference:ItsusecouldresultinaNullReferenceException 使用參數呼叫方法out 當呼叫Deconstruct方法解構使用者定義型別(類別、結構或介面的執行個體)時,您可以捨棄個別out引數的值。

但是,您也可以在out使用參數呼叫任何方法時,捨棄引數的值out。

下列範例會呼叫DateTime.TryParse(String,outDateTime)方法,以判斷日期的字串表示在目前的文化特性(culture)中是否有效。

因為此範例只需要驗證日期字串,而不需要將它剖析以擷取日期,所以該方法的out引數為discard。

string[]dateStrings={"05/01/201814:57:32.8","2018-05-0114:57:32.8", "2018-05-01T14:57:32.8375298-04:00","5/01/2018", "5/01/201814:57:32.80-07:00", "1May20182:57:32.8PM","16-05-20181:00:32PM", "Fri,15May201820:10:57GMT"}; foreach(stringdateStringindateStrings) { if(DateTime.TryParse(dateString,out_)) Console.WriteLine($"'{dateString}':valid"); else Console.WriteLine($"'{dateString}':invalid"); } //Theexampledisplaysoutputlikethefollowing: //'05/01/201814:57:32.8':valid //'2018-05-0114:57:32.8':valid //'2018-05-01T14:57:32.8375298-04:00':valid //'5/01/2018':valid //'5/01/201814:57:32.80-07:00':valid //'1May20182:57:32.8PM':valid //'16-05-20181:00:32PM':invalid //'Fri,15May201820:10:57GMT':invalid 獨立discard 您可以使用獨立discard,指出您選擇忽略的任何變數。

其中一個典型的用法是使用指派,以確保引數不是null。

下列程式碼會使用捨棄來強制執行指派。

當引數為時,指派的右邊會使用null聯合運算子來擲回System.ArgumentNullExceptionnull。

程式碼不需要指派的結果,所以會予以捨棄。

運算式會強制執行null檢查。

捨棄將說明您的意圖:不需要或使用指派的結果。

publicstaticvoidMethod(stringarg) { _=arg??thrownewArgumentNullException(paramName:nameof(arg),message:"argcan'tbenull"); //Doworkwitharg. } 下列範例會使用獨立discard來忽略非同步作業傳回的Task物件。

指派工作的效果是隱藏作業在即將完成時擲回的例外狀況。

這會讓您的意圖清楚:您想要捨棄Task,並忽略該非同步作業所產生的任何錯誤。

privatestaticasyncTaskExecuteAsyncMethods() { Console.WriteLine("Abouttolaunchatask..."); _=Task.Run(()=> { variterations=0; for(intctr=0;ctr { variterations=0; for(intctr=0;ctr



請為這篇文章評分?