is模式匹配

is运算符用来检测一个对象是不是某种类型。

回想一下,C#支持继承和接口实现。

而且,任何类都只能继承一个类,它的父类也只能继承另一个基类,以此类推。

虽然C#不允许多继承,但是类却可以实现任意多个接口

在这种复杂性下,is运算符不仅能检测当前类的类型,还能检测任意层次的基类,以及是否支持指定的接口。

下面的例子说明了这一点:

C#
  public interface IOne
   {
       int SampleIntProperty { get; set; }
   }

   public interface ITwo 
   {
       int SampleIntProperty2 { get; set; }
   }

   public class BaseClass
   {
       public string? SampleStringProperty { get; set; }
   }

   public class DerivedClass : BaseClass, IOne, ITwo
   {
       public int SampleIntProperty { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
       public int SampleIntProperty2 { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
   }
   
   
   
      static async Task Main(string[] args)
   {
       var dc = new DerivedClass();

       if (dc is DerivedClass)
       {
           await Console.Out.WriteLineAsync("Derived Class found");
       }
       if (dc is BaseClass)
       {
           await Console.Out.WriteLineAsync("Base Class found");
       }
       if(dc is IOne)
       {
           await Console.Out.WriteLineAsync("Interface One found");
       }
       if (dc is ITwo)
       {
           await Console.Out.WriteLineAsync("Interface Two found");
       }
   

   }

这段代码的输出如下:

检测了一个给定对象是不是某种类型后,如果想引用这种类型,就必须先转换成这种类型。

C#
  double myEmp = 0;
  if (myEmp is double)
  {
      var myInt = (int)myEmp;
  }

也可以使用as运算符来实现这种转换

C#
 string myEmp = string.Empty;
 var myInt = myEmp as object;

在C#7.0中,is运算符的类型语法已简化,可以直接给检测类(或者其他类型)后的变量赋值。

增强的is运算符不仅检测变量类型,如果变量通过了检测,还可以同时将其赋值给指定的新变量。

这个新的变量叫作匹配变量(match variable)。

C#
 string myEMP = string.Empty;

 if(myEMP is string mySub)
 {
     //如果检测通过了,mySub变量立即就可以使用
     await Console.Out.WriteLineAsync($"My Sub name is{mySub}");
 }

事实上,这个新赋值的匹配变量甚至可以在包含is检测的表达式中使用。

C#
 if (myEMP is string mySub && mySub == "Fired") await Console.Out.WriteLineAsync("ABS");

匹配变量的作用域仅仅是这个检测块。

C#
  if (myEMP is string mySub && mySub == "Fired")
  {
      //这里是mySub变量的作用域
  }

除了引用类型,is运算符现在也可以应用于值类型了。

这意味着现在不仅可以检测类,也可以检测结构体了。

订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
滚动至顶部