c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换

 更新时间:2020年10月13日 10:37:03   作者:olprod  
这篇文章主要介绍了c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下

由于是多态对象,基类类型的变量可以保存派生类型。 要访问派生类型的实例成员,必须将值强制转换回派生类型。 但是,强制转换会引发 InvalidCastException 风险。 C# 提供模式匹配语句,该语句只有在成功时才会有条件地执行强制转换。 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) 语句将测试与初始化赋值相结合。 只有在测试成功时才会进行赋值。 变量 m 仅在已赋值的嵌入式 if 语句的范围内。 以后无法在同一方法中访问 m。 前面的示例还演示了如何使用 as 运算符将对象转换为指定类型。
也可以使用同一语法来测试可为 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;
    }
  }
}

前面的示例演示了模式匹配用于转换的其他功能。 可以通过专门检查 null 值来测试 NULL 模式的变量。 当变量的运行时值为 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());
    }
  }
}

正如你所看到的,将此代码与模式匹配代码进行比较,模式匹配语法通过在单个语句中结合测试和赋值来提供更强大的功能。 尽量使用模式匹配语法。

以上就是c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换的详细内容,更多关于c# 强制转换的资料请关注脚本之家其它相关文章!

相关文章

  • C#实现在线点餐系统

    C#实现在线点餐系统

    这篇文章主要为大家详细介绍了C#实现在线点餐系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • C#提取PPT文本和图片的实现方法

    C#提取PPT文本和图片的实现方法

    这篇文章主要为大家详细介绍了C#提取PPT文本和图片的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • C#把文件上传到服务器中的指定地址

    C#把文件上传到服务器中的指定地址

    这篇文章介绍了C#实现文件上传到服务器指定地址的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 简单聊聊C#的线程本地存储TLS到底是什么

    简单聊聊C#的线程本地存储TLS到底是什么

    C#的ThreadStatic是假的,因为C#完全是由CLR(C++)承载的,言外之意C#的线程本地存储,用的就是用C++运行时提供的 __declspec(thread)或__thread来虚构的一套玩法,下面我们就来深入讲讲C#的线程本地存储TLS到底是什么吧
    2024-01-01
  • C#序列化成XML注意细节

    C#序列化成XML注意细节

    最常用的序列化是把某个类序列化成二进制文件.但有时我们也会把类序列化成xml文件,需要的朋友可以参考下
    2012-11-11
  • 实例代码讲解c# 线程(上)

    实例代码讲解c# 线程(上)

    这篇文章主要介绍了讲解c# 线程的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C#简单的特殊输出实例

    C#简单的特殊输出实例

    这篇文章主要介绍了C#简单的特殊输出,以实例实现了针对一些特殊字符与位置的输出控制,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-11-11
  • C#判断某程序是否运行的方法

    C#判断某程序是否运行的方法

    这篇文章主要介绍了C#判断某程序是否运行的方法,代码结构简单功能实用,需要的朋友可以参考下
    2014-09-09
  • C#实现简单的计算器功能(窗体)

    C#实现简单的计算器功能(窗体)

    这篇文章主要为大家详细介绍了C#实现简单的计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C# 判断字符串为空的几种办法

    C# 判断字符串为空的几种办法

    C# 判断字符串为空的几种办法,需要的朋友可以参考一下
    2013-04-04

最新评论