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-07
C#筆記之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-09
C#?微信支付回調(diào)驗(yàn)簽處理的實(shí)現(xiàn)
在微信支付中,當(dāng)用戶支付成功后,微信會(huì)把相關(guān)支付結(jié)果和用戶信息發(fā)送給商戶,本文就詳細(xì)的介紹了C#?微信支付回調(diào)驗(yàn)簽處理,具有一定的參考價(jià)值,感興趣的可以了解一下2021-12-12
C#使用linq計(jì)算執(zhí)行元素在列表中出現(xiàn)次數(shù)的方法
這篇文章主要介紹了C#使用linq計(jì)算執(zhí)行元素在列表中出現(xiàn)次數(shù)的方法,涉及C#使用linq擴(kuò)展進(jìn)行列表查詢的技巧,需要的朋友可以參考下2015-04-04
C#實(shí)現(xiàn)常見(jiàn)加密算法的示例代碼
這篇文章主要為大家詳細(xì)介紹一下C#中一些常見(jiàn)加密算法(Base64編碼、凱撒密碼、Vigenere密碼、DES、AES)以及它們的實(shí)現(xiàn)代碼,感興趣的可以了解一下2022-07-07
C#備忘錄人生存檔的設(shè)計(jì)模式實(shí)例
這篇文章主要為大家介紹了C#設(shè)計(jì)模式中備忘錄模式的實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

