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

由于是多态对象,基类类型的变量可以保存派生类型。 要访问派生类型的实例成员,必须将值强制转换回派生类型。 但是,强制转换会引发 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# 强制转换的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解c# 强制转换和类型转换

    由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或无法分配另一种类型的值,除非该类型可以隐式转换为变量的类型. 例如,string 无法隐式转换为 int. 因此,在将 i 声明为 int 后,无法将字符串"Hello"分配给它,如以下代码所示: int i; // error CS0029: Cannot implicitly convert type 'string' to 'int' i = "Hello"; 但有时可能需要将值复制到其他类

  • C#日期格式强制转换方法(推荐)

    C#编写winform程序时,用到的,格式强转,存储到数据库,数据库连接那块就不写了 希望对大家有帮助,欢迎评论互相分享技术! //日期格式强制转化 string str1 = deStartDate.EditValue.ToString(); DateTime date; DateTime.TryParse(str1, out date); str1 = date.ToString("yyyy/MM/dd"); string str2 = deDueDate.EditValue.To

  • C# 9.0 新特性之模式匹配简化的实现

    记得在 MS Build 2020 大会上,C# 语言开发项目经理 Mads Torgersen 宣称 C# 9.0 将会随着 .NET 5 在今年 11 月份正式发布.目前 .NET 5 已经到了 Preview 5 阶段了,C# 9.0 也已经初具规模.忍不住激动的心情,暂停更新<C#.NET 拾遗补漏>系列几天,先要和大家分享一下我了解到的 C# 9.0 的新特性.由于新特性比较多,所以会分成几篇来讲.这是第一篇,专讲模式匹配这个特性的简化. 模式匹配(Pattern Matching)

  • C#自定义类型强制转换实例分析

    本文实例讲述了C#自定义类型强制转换的用法.分享给大家供大家参考.具体分析如下: 先来举一个小例子 类定义: public class MyCurrency { public uint Dollars; public ushort Cents; public MyCurrency(uint dollars, ushort cents) { this.Dollars = dollars; this.Cents = cents; } public override string ToString()

  • C#强制转换和尝试转换的方法

    本文实例为大家分享了C#强制转换和尝试转换的方法,供大家参考,具体内容如下 将String[]类型的Object类型,转换为String[]类型: public string ObjectToString(object ob) { string str = string.Empty; if (ob is string[]) { string[] strList = (string[])ob; } return str; } 使用 is 进行判断 ob 是否为 string[] 类型. 将 str

  • C#中is与As运算符号的使用详解

    如下所示: 复制代码 代码如下: using System;using System.Collections.Generic;using System.Text;namespace ConsoleApplication1{    class IsOrAsClass    {        class Animal        {            public void Eat()            {                Console.WriteLine("Eating.

  • C#8 的模式匹配实现

    C# 7 里面的Pattern Mathing 更多内容请查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8#more-patterns-in-more-places?WT.mc_id=DT-MVP-5003302 is 模式 switch 和 when C# 8 里面的Pattern Matching 使用Deconstructor 和 位置匹配模式 下面两个类Teacher和Student都由构造函

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

    由于是多态对象,基类类型的变量可以保存派生类型. 要访问派生类型的实例成员,必须将值强制转换回派生类型. 但是,强制转换会引发 InvalidCastException 风险. C# 提供模式匹配语句,该语句只有在成功时才会有条件地执行强制转换. C# 还提供 is 和 as 运算符来测试值是否属于特定类型. 下面的示例演示如何使用模式匹配 is 语句: class Animal { public void Eat() { Console.WriteLine("Eating."); }

  • C#自动类型转换与强制类型转换的讲解

    自动类型转换 隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失.例如,从小的整数类型转换为大的整数类型,从派生类转换为基类. 转换规则 从存储范围小的类型到存储范围大的类型. 整数具体规则为: byte→short(char)→int→long→float→double 也就是说byte类型的变量可以自动转换为short类型,示例代码: byte b = 10; short sh = b; 在类型转换时可以跳跃.示例代码: byte b1 = 100; int

  • C#数据类型及其转换详解

    前言 在C#中,数据类型可以分为以下几种类型: 值类型(Value types)引用类型(Reference types)指针类型(Pointer types) 其中指针类型只在不安全代码下使用,一般不涉及所以今天不讨论.我们主要探讨引用类型和值类型. 一.基本定义 值类型的变量在声明后,系统直接在托管栈中为其分配内存并保存其数据,其中值类型包括:byte,short,int,long,float,double,decimal,char,bool 和 struct等,当我们声明一个引用类型时,系

  • 详解c# 类型转换

    类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型.在 C# 中,类型铸造有两种形式: 隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失.例如,从小的整数类型转换为大的整数类型,从派生类转换为基类. 显式类型转换 - 显式类型转换,即强制类型转换.显式转换需要强制转换运算符,而且强制转换会造成数据丢失. 下面的实例显示了一个显式的类型转换: namespace TypeConversionApplication { class Explici

  • Python全栈之学习JS(1)

    目录 1. js的数据类型 1.1 js引入方式 1.2 注释变量 1.3 数据类型 2. js类型转换_运算符 2.1 强制转换_Number 2.2 强制转换_String 2.3 强制转换_Boolean 2.4 自动类型转换_Number_Boolean_String三者之间转换 2.5 js运算符 3. js流程控制 3.1 分支结构 3.2 分支结构_switch_case 3.3 循环结构 4. js函数 4.1 函数 4.2 函数的调用 总结 1. js的数据类型 1.1 js引

  • 详解C#数据类型及其转换

    前言 在C#中,数据类型可以分为以下几种类型: 值类型(Value types)引用类型(Reference types)指针类型(Pointer types) 其中指针类型只在不安全代码下使用,一般不涉及所以今天不讨论.我们主要探讨引用类型和值类型. 一.基本定义 值类型的变量在声明后,系统直接在托管栈中为其分配内存并保存其数据,其中值类型包括:byte,short,int,long,float,double,decimal,char,bool 和 struct等,当我们声明一个引用类型时,系

  • Swift 5.1 之类型转换与模式匹配的教程详解

    类型转换在Swift中使用 is 和 as 操作符实现. 类型检查 使用操作符 is 检查一个实例是否是某个确定的类以及其继承体系的父类或子类类型.如果是某个确定的类(该类继承体系的父类或子类)类型,则返回 true ,否则返回 false . class Cat { func hairColor() -> String { return "五颜六色" } } class WhiteCat: Cat { override func hairColor() -> String

  • C语言运算符优先级列表(超详细)

    每当想找哪个运算符优先级高时,很多时候总是想找的就没有,真让人气愤!现在,终于有个我个人觉得非常全的,分享给大家,欢迎拍砖! C语言运算符优先级 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- -> 成员选择(指针) 对象指针->成员名 -- 2 - 负号运算符 -表达式 右到左 单目运算符 ~ 按位取反运算符 ~表达式 ++ 自增运算符 +

  • Java 运算符 动力节点Java学院整理

    Java的运算符,分为四类: 算数运算符.关系运算符.逻辑运算符.位运算符. 算数运算符(9):+ - * / % ++ -- 关系运算符(6):== != > >= < <= 逻辑运算符(6):&& || ! ^ & | 位运算符(7):& | ~ ^ >> << >>> Java基本数据类型: 数值类型: 整型:byte.short.int.long 非整型:double.float 非数值类型:char

随机推荐