c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换
由于是多态对象,基类类型的变量可以保存派生类型。要访问派生类型的实例成员,必须将值强制转换回派生类型。但是,强制转换会引发InvalidCastException风险。C#提供模式匹配语句,该语句只有在成功时才会有条件地执行强制转换。C#还提供is和as运算符来测试值是否属于特定类型。
下面的示例演示如何使用模式匹配is语句:
classAnimal
{
publicvoidEat(){Console.WriteLine("Eating.");}
publicoverridestringToString()
{
return"Iamananimal.";
}
}
classMammal:Animal{}
classGiraffe:Mammal{}
classSuperNova{}
classProgram
{
staticvoidMain(string[]args)
{
varg=newGiraffe();
vara=newAnimal();
FeedMammals(g);
FeedMammals(a);
//Output:
//Eating.
//AnimalisnotaMammal
SuperNovasn=newSuperNova();
TestForMammals(g);
TestForMammals(sn);
//Output:
//Iamananimal.
//SuperNovaisnotaMammal
}
staticvoidFeedMammals(Animala)
{
if(aisMammalm)
{
m.Eat();
}
else
{
//variable'm'isnotinscopehere,andcan'tbeused.
Console.WriteLine($"{a.GetType().Name}isnotaMammal");
}
}
staticvoidTestForMammals(objecto)
{
//Youalsocanusetheasoperatorandtestfornull
//beforereferencingthevariable.
varm=oasMammal;
if(m!=null)
{
Console.WriteLine(m.ToString());
}
else
{
Console.WriteLine($"{o.GetType().Name}isnotaMammal");
}
}
}
前面的示例演示了模式匹配语法的一些功能。if(aisMammalm)语句将测试与初始化赋值相结合。只有在测试成功时才会进行赋值。变量m仅在已赋值的嵌入式if语句的范围内。以后无法在同一方法中访问m。前面的示例还演示了如何使用as运算符将对象转换为指定类型。
也可以使用同一语法来测试可为null的值类型是否具有值,如以下示例所示:
classProgram
{
staticvoidMain(string[]args)
{
inti=5;
PatternMatchingNullable(i);
int?j=null;
PatternMatchingNullable(j);
doubled=9.78654;
PatternMatchingNullable(d);
PatternMatchingSwitch(i);
PatternMatchingSwitch(j);
PatternMatchingSwitch(d);
}
staticvoidPatternMatchingNullable(System.ValueTypeval)
{
if(valisintj)//Nullabletypesarenotallowedinpatterns
{
Console.WriteLine(j);
}
elseif(valisnull)//Ifvalisanullabletypewithnovalue,thisexpressionistrue
{
Console.WriteLine("valisanullabletypewiththenullvalue");
}
else
{
Console.WriteLine("Couldnotconvert"+val.ToString());
}
}
staticvoidPatternMatchingSwitch(System.ValueTypeval)
{
switch(val)
{
caseintnumber:
Console.WriteLine(number);
break;
caselongnumber:
Console.WriteLine(number);
break;
casedecimalnumber:
Console.WriteLine(number);
break;
casefloatnumber:
Console.WriteLine(number);
break;
casedoublenumber:
Console.WriteLine(number);
break;
casenull:
Console.WriteLine("valisanullabletypewiththenullvalue");
break;
default:
Console.WriteLine("Couldnotconvert"+val.ToString());
break;
}
}
}
前面的示例演示了模式匹配用于转换的其他功能。可以通过专门检查null值来测试NULL模式的变量。当变量的运行时值为null时,用于检查类型的is语句始终返回false。模式匹配is语句不允许可以为null值的类型,如int?或Nullable
前面的示例还演示如何在变量为其他类型的switch语句中使用类型模式。
如果需要测试变量是否为给定类型,但不将其分配给新变量,则可以对引用类型和可以为null的值类型使用is和as运算符。以下代码演示如何在引入模式匹配以测试变量是否为给定类型前,使用C#语言中的is和as语句:
classAnimal
{
publicvoidEat(){Console.WriteLine("Eating.");}
publicoverridestringToString()
{
return"Iamananimal.";
}
}
classMammal:Animal{}
classGiraffe:Mammal{}
classSuperNova{}
classProgram
{
staticvoidMain(string[]args)
{
//Usetheisoperatortoverifythetype.
//beforeperformingacast.
Giraffeg=newGiraffe();
UseIsOperator(g);
//Usetheasoperatorandtestfornull
//beforereferencingthevariable.
UseAsOperator(g);
//Usetheasoperatortotest
//anincompatibletype.
SuperNovasn=newSuperNova();
UseAsOperator(sn);
//Usetheasoperatorwithavaluetype.
//Notetheimplicitconversiontoint?in
//themethodbody.
inti=5;
UseAsWithNullable(i);
doubled=9.78654;
UseAsWithNullable(d);
}
staticvoidUseIsOperator(Animala)
{
if(aisMammal)
{
Mammalm=(Mammal)a;
m.Eat();
}
}
staticvoidUsePatternMatchingIs(Animala)
{
if(aisMammalm)
{
m.Eat();
}
}
staticvoidUseAsOperator(objecto)
{
Mammalm=oasMammal;
if(m!=null)
{
Console.WriteLine(m.ToString());
}
else
{
Console.WriteLine($"{o.GetType().Name}isnotaMammal");
}
}
staticvoidUseAsWithNullable(System.ValueTypeval)
{
int?j=valasint?;
if(j!=null)
{
Console.WriteLine(j);
}
else
{
Console.WriteLine("Couldnotconvert"+val.ToString());
}
}
}
正如你所看到的,将此代码与模式匹配代码进行比较,模式匹配语法通过在单个语句中结合测试和赋值来提供更强大的功能。尽量使用模式匹配语法。
以上就是c#使用模式匹配以及is和as运算符安全地进行强制转换的详细内容,更多关于c#强制转换的资料请关注毛票票其它相关文章!