c# 使用模式匹配以及 is 和 as 運算符安全地進行強制轉(zhuǎn)換
由于是多態(tài)對象,基類類型的變量可以保存派生類型。 要訪問派生類型的實例成員,必須將值強制轉(zhuǎn)換回派生類型。 但是,強制轉(zhuǎn)換會引發(fā) InvalidCastException 風(fēng)險。 C# 提供模式匹配語句,該語句只有在成功時才會有條件地執(zhí)行強制轉(zhuǎn)換。 C# 還提供 is 和 as 運算符來測試值是否屬于特定類型。
下面的示例演示如何使用模式匹配 is 語句:
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");
}
}
}
前面的示例演示了模式匹配語法的一些功能。 if (a is Mammal m) 語句將測試與初始化賦值相結(jié)合。 只有在測試成功時才會進行賦值。 變量 m 僅在已賦值的嵌入式 if 語句的范圍內(nèi)。 以后無法在同一方法中訪問 m。 前面的示例還演示了如何使用 as 運算符將對象轉(zhuǎn)換為指定類型。
也可以使用同一語法來測試可為 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)換的其他功能。 可以通過專門檢查 null 值來測試 NULL 模式的變量。 當(dāng)變量的運行時值為 null 時,用于檢查類型的 is 語句始終返回 false。 模式匹配 is 語句不允許可以為 null 值的類型,如 int? 或 Nullable<int>,但你可以測試任何其他值類型。 上述示例中的 is 模式不局限于可為空的值類型。 也可以使用這些模式測試引用類型的變量具有值還是為 null。
前面的示例還演示如何在變量為其他類型的 switch 語句中使用類型模式。
如果需要測試變量是否為給定類型,但不將其分配給新變量,則可以對引用類型和可以為 null 的值類型使用 is 和 as 運算符。 以下代碼演示如何在引入模式匹配以測試變量是否為給定類型前,使用 C# 語言中的 is 和 as 語句:
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());
}
}
}
正如你所看到的,將此代碼與模式匹配代碼進行比較,模式匹配語法通過在單個語句中結(jié)合測試和賦值來提供更強大的功能。 盡量使用模式匹配語法。
以上就是c# 使用模式匹配以及 is 和 as 運算符安全地進行強制轉(zhuǎn)換的詳細內(nèi)容,更多關(guān)于c# 強制轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!

