服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换

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

2022-10-11 14:40olprod C#

这篇文章主要介绍了c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下

由于是多态对象,基类类型的变量可以保存派生类型。 要访问派生类型的实例成员,必须将值强制转换回派生类型。 但是,强制转换会引发 InvalidCastException 风险。 C# 提供模式匹配语句,该语句只有在成功时才会有条件地执行强制转换。 C# 还提供 is 和 as 运算符来测试值是否属于特定类型。

下面的示例演示如何使用模式匹配 is 语句:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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 的值类型是否具有值,如以下示例所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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 语句:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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# 强制转换的资料请关注服务器之家其它相关文章!

原文链接:https://github.com/dotnet/docs.zh-cn/blob/live/docs/csharp/how-to/safely-cast-using-pattern-matching-is-and-as-operators.md

延伸 · 阅读

精彩推荐
  • C#c# 用Base64实现文件上传

    c# 用Base64实现文件上传

    这篇文章主要介绍了c# 用Base64实现文件上传的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...

    Charles_Su7062022-09-29
  • C#C#学习教程之Socket的简单使用

    C#学习教程之Socket的简单使用

    这篇文章主要给大家介绍了关于C#学习教程之Socket的简单使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    张子浩8602022-03-09
  • C#c# 插入数据效率测试(mongodb)

    c# 插入数据效率测试(mongodb)

    这篇文章主要介绍了c# 插入数据效率测试(mongodb),插入的速度要比Mysql和sqlserver都要快需要的朋友可以参考下...

    chenqiangdage9972022-02-21
  • C#Unity实现简单虚拟摇杆(附代码)

    Unity实现简单虚拟摇杆(附代码)

    这篇文章主要为大家详细介绍了Unity实现简单虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    臣定保幼主周全ぃ3492022-09-01
  • C#WinForm生成验证码图片的方法

    WinForm生成验证码图片的方法

    这篇文章主要介绍了WinForm生成验证码图片的方法,涉及WinForm字符串及图形操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    aparche4842021-11-24
  • C#C#制作简易的屏保

    C#制作简易的屏保

    这篇文章主要为大家详细介绍了C#制作简易的屏保的相关资料,C#如何制作屏保的过程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    邪心魔佛一页书5932021-12-16
  • C#Unity实现手机摇一摇震动

    Unity实现手机摇一摇震动

    这篇文章主要为大家详细介绍了untiy实现手机摇一摇震动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    liang_7049597218622022-08-09
  • C#利用Aspose.Cells和Excel模板导出统计数据

    利用Aspose.Cells和Excel模板导出统计数据

    这篇文章主要为大家详细介绍了利用Aspose.Cells和Excel模板导出复杂的统计数据,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    蝶恋花雨8302022-03-06