c# 使用模式匹配以及 is 和 as 運(yùn)算符安全地進(jìn)行強(qiáng)制轉(zhuǎn)換
由于是多態(tài)對(duì)象,基類類型的變量可以保存派生類型。 要訪問(wèn)派生類型的實(shí)例成員,必須將值強(qiáng)制轉(zhuǎn)換回派生類型。 但是,強(qiáng)制轉(zhuǎn)換會(huì)引發(fā) InvalidCastException 風(fēng)險(xiǎn)。 C# 提供模式匹配語(yǔ)句,該語(yǔ)句只有在成功時(shí)才會(huì)有條件地執(zhí)行強(qiáng)制轉(zhuǎn)換。 C# 還提供 is 和 as 運(yùn)算符來(lái)測(cè)試值是否屬于特定類型。
下面的示例演示如何使用模式匹配 is 語(yǔ)句:
class Animal { public void Eat() { Console.WriteLine("Eating."); } public override string ToString() { return "I am an animal."; } } class Mammal : Animal { } class Giraffe : Mammal { } class SuperNova { } class Program { static void Main(string[] args) { var g = new Giraffe(); var a = new Animal(); FeedMammals(g); FeedMammals(a); // Output: // Eating. // Animal is not a Mammal SuperNova sn = new SuperNova(); TestForMammals(g); TestForMammals(sn); // Output: // I am an animal. // SuperNova is not a Mammal } static void FeedMammals(Animal a) { if (a is Mammal m) { m.Eat(); } else { // variable 'm' is not in scope here, and can't be used. Console.WriteLine($"{a.GetType().Name} is not a Mammal"); } } static void TestForMammals(object o) { // You also can use the as operator and test for null // before referencing the variable. var m = o as Mammal; if (m != null) { Console.WriteLine(m.ToString()); } else { Console.WriteLine($"{o.GetType().Name} is not a Mammal"); } } }
前面的示例演示了模式匹配語(yǔ)法的一些功能。 if (a is Mammal m) 語(yǔ)句將測(cè)試與初始化賦值相結(jié)合。 只有在測(cè)試成功時(shí)才會(huì)進(jìn)行賦值。 變量 m 僅在已賦值的嵌入式 if 語(yǔ)句的范圍內(nèi)。 以后無(wú)法在同一方法中訪問(wèn) m。 前面的示例還演示了如何使用 as 運(yùn)算符將對(duì)象轉(zhuǎn)換為指定類型。
也可以使用同一語(yǔ)法來(lái)測(cè)試可為 null 的值類型是否具有值,如以下示例所示:
class Program { static void Main(string[] args) { int i = 5; PatternMatchingNullable(i); int? j = null; PatternMatchingNullable(j); double d = 9.78654; PatternMatchingNullable(d); PatternMatchingSwitch(i); PatternMatchingSwitch(j); PatternMatchingSwitch(d); } static void PatternMatchingNullable(System.ValueType val) { if (val is int j) // Nullable types are not allowed in patterns { Console.WriteLine(j); } else if (val is null) // If val is a nullable type with no value, this expression is true { Console.WriteLine("val is a nullable type with the null value"); } else { Console.WriteLine("Could not convert " + val.ToString()); } } static void PatternMatchingSwitch(System.ValueType val) { switch (val) { case int number: Console.WriteLine(number); break; case long number: Console.WriteLine(number); break; case decimal number: Console.WriteLine(number); break; case float number: Console.WriteLine(number); break; case double number: Console.WriteLine(number); break; case null: Console.WriteLine("val is a nullable type with the null value"); break; default: Console.WriteLine("Could not convert " + val.ToString()); break; } } }
前面的示例演示了模式匹配用于轉(zhuǎn)換的其他功能。 可以通過(guò)專門檢查 null 值來(lái)測(cè)試 NULL 模式的變量。 當(dāng)變量的運(yùn)行時(shí)值為 null 時(shí),用于檢查類型的 is 語(yǔ)句始終返回 false。 模式匹配 is 語(yǔ)句不允許可以為 null 值的類型,如 int? 或 Nullable<int>,但你可以測(cè)試任何其他值類型。 上述示例中的 is 模式不局限于可為空的值類型。 也可以使用這些模式測(cè)試引用類型的變量具有值還是為 null。
前面的示例還演示如何在變量為其他類型的 switch 語(yǔ)句中使用類型模式。
如果需要測(cè)試變量是否為給定類型,但不將其分配給新變量,則可以對(duì)引用類型和可以為 null 的值類型使用 is 和 as 運(yùn)算符。 以下代碼演示如何在引入模式匹配以測(cè)試變量是否為給定類型前,使用 C# 語(yǔ)言中的 is 和 as 語(yǔ)句:
class Animal { public void Eat() { Console.WriteLine("Eating."); } public override string ToString() { return "I am an animal."; } } class Mammal : Animal { } class Giraffe : Mammal { } class SuperNova { } class Program { static void Main(string[] args) { // Use the is operator to verify the type. // before performing a cast. Giraffe g = new Giraffe(); UseIsOperator(g); // Use the as operator and test for null // before referencing the variable. UseAsOperator(g); // Use the as operator to test // an incompatible type. SuperNova sn = new SuperNova(); UseAsOperator(sn); // Use the as operator with a value type. // Note the implicit conversion to int? in // the method body. int i = 5; UseAsWithNullable(i); double d = 9.78654; UseAsWithNullable(d); } static void UseIsOperator(Animal a) { if (a is Mammal) { Mammal m = (Mammal)a; m.Eat(); } } static void UsePatternMatchingIs(Animal a) { if (a is Mammal m) { m.Eat(); } } static void UseAsOperator(object o) { Mammal m = o as Mammal; if (m != null) { Console.WriteLine(m.ToString()); } else { Console.WriteLine($"{o.GetType().Name} is not a Mammal"); } } static void UseAsWithNullable(System.ValueType val) { int? j = val as int?; if (j != null) { Console.WriteLine(j); } else { Console.WriteLine("Could not convert " + val.ToString()); } } }
正如你所看到的,將此代碼與模式匹配代碼進(jìn)行比較,模式匹配語(yǔ)法通過(guò)在單個(gè)語(yǔ)句中結(jié)合測(cè)試和賦值來(lái)提供更強(qiáng)大的功能。 盡量使用模式匹配語(yǔ)法。
以上就是c# 使用模式匹配以及 is 和 as 運(yùn)算符安全地進(jìn)行強(qiáng)制轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于c# 強(qiáng)制轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#創(chuàng)建SQLite控制臺(tái)應(yīng)用程序詳解
這篇文章主要為大家詳細(xì)介紹了C#創(chuàng)建SQLite控制臺(tái)應(yīng)用程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07C#筆記之EF Code First 數(shù)據(jù)模型 數(shù)據(jù)遷移
EF 中 Code First 的數(shù)據(jù)遷移網(wǎng)上有很多資料,我這份并沒(méi)什么特別。Code First 創(chuàng)建視圖網(wǎng)上也有很多資料,但好像很麻煩,而且親測(cè)好像是無(wú)效的方法(可能是我太笨,沒(méi)搞成功),我摸索出了一種簡(jiǎn)單有效的方法,這里分享給大家2021-09-09C#?微信支付回調(diào)驗(yàn)簽處理的實(shí)現(xiàn)
在微信支付中,當(dāng)用戶支付成功后,微信會(huì)把相關(guān)支付結(jié)果和用戶信息發(fā)送給商戶,本文就詳細(xì)的介紹了C#?微信支付回調(diào)驗(yàn)簽處理,具有一定的參考價(jià)值,感興趣的可以了解一下2021-12-12C#使用linq計(jì)算執(zhí)行元素在列表中出現(xiàn)次數(shù)的方法
這篇文章主要介紹了C#使用linq計(jì)算執(zhí)行元素在列表中出現(xiàn)次數(shù)的方法,涉及C#使用linq擴(kuò)展進(jìn)行列表查詢的技巧,需要的朋友可以參考下2015-04-04C#實(shí)現(xiàn)常見(jiàn)加密算法的示例代碼
這篇文章主要為大家詳細(xì)介紹一下C#中一些常見(jiàn)加密算法(Base64編碼、凱撒密碼、Vigenere密碼、DES、AES)以及它們的實(shí)現(xiàn)代碼,感興趣的可以了解一下2022-07-07C#備忘錄人生存檔的設(shè)計(jì)模式實(shí)例
這篇文章主要為大家介紹了C#設(shè)計(jì)模式中備忘錄模式的實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06