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

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

is 运算符

用于检查一个对象是否是特定类型。C# 7 引入了 is 运算符的模式匹配功能,可以在检查类型的同时进行类型转换

csharp 复制代码
object obj = "Hello, world!";

if (obj is string str)
{
    Console.WriteLine($"String length: {str.Length}");
}

is 运算符不仅检查 obj 是否是 string 类型,还将其转换为 str 变量,并在条件块中使用。这样可以避免不必要的显式转换,提高代码的安全性和简洁性。

as 运算符

运算符用于尝试将一个对象转换为特定类型。如果转换成功,则返回转换后的对象;如果转换失败,则返回 null

csharp 复制代码
object obj = "Hello, world!";
string str = obj as string;

if (str != null)
{
    Console.WriteLine($"String length: {str.Length}");
}
else
{
    Console.WriteLine("obj is not a string.");
}

这里 obj 被尝试转换为 string 类型,并赋值给 str。随后可以通过 str != null 来检查转换是否成功,从而避免不安全的显式类型转换。

模式匹配

C# 7 引入了模式匹配特性,使得你可以在 switch 语句和 is 运算符中结合模式进行类型检查和转换

csharp 复制代码
object obj = 42;

switch (obj)
{
    case int i:
        Console.WriteLine($"Integer: {i}");
        break;
    case string s:
        Console.WriteLine($"String: {s}");
        break;
    default:
        Console.WriteLine("Unknown type.");
        break;
}

这里 switch 语句通过模式匹配直接检查 obj 的类型,并将其转换为对应的类型变量 i 或 s。这种方式不仅简化了类型检查的代码,还确保了类型转换的安全性。

使用场景

  • 类型检查:在处理未知类型的对象时,使用 is 或模式匹配可以进行类型检查并转换,避免了不安全的显式转换。
  • 多态性:在继承关系中,is 和 as 可以用于检查和转换对象为基类或子类,这可以在运行时决定对象的具体类型。
  • 代码简洁性:模式匹配可以结合 switch 语句或 is 来简化类型检查和转换的代码逻辑,使其更易读。

拓展

  • is 和 as 运算符在类型检查和转换时,会考虑对象的实际类型以及继承关系
csharp 复制代码
class Animal {}
class Dog : Animal {}

object obj = new Dog();

if (obj is Animal animal) {
    Console.WriteLine("It's an Animal.");
}

Animal animal = obj as Animal;

if (animal != null) {
    Console.WriteLine("It's an Animal.");
}

obj 是 Dog 的实例,但 Dog 继承自 Animal,所以 is Animal 检查会成功,并将 obj 转换为 animal

父类和子类的检查

is 和 as 运算符都可以识别并转换父类和子类之间的关系。

  • 向上转换(Upcasting):将子类转换为父类是安全的,也可以直接使用 is 或 as 来实现。
  • 向下转换(Downcasting):如果需要将父类转换为子类,你需要确保类型匹配,否则转换会失败。
csharp 复制代码
Animal animal = new Dog();
Dog dog = animal as Dog;

if (dog != null) {
    Console.WriteLine("It's a Dog.");
}

在这里,我们将 animal 向下转换为 Dog。如果 animal 实际上不是 Dog 的实例,则转换会失败,dog 会是 null。

  • 继承链的完整性:is 和 as 会识别整个继承链。因此,你可以使用它们来检查父类、子类甚至兄弟类之间的关系。

校验与对象类型

is 和 as 在类型检查和转换时,并不一定要求目标类型是 object。

is 和 as 运算符在类型检查和转换时,也可以用于泛型类型。

csharp 复制代码
class Box<T> {}

object obj = new Box<int>();

if (obj is Box<int> boxInt) {
    Console.WriteLine("It's a Box<int>.");
}
csharp 复制代码
Box<string> boxString = new Box<string>();
object obj = boxString;

Box<string> convertedBox = obj as Box<string>;

if (convertedBox != null) {
    Console.WriteLine("Successfully converted to Box<string>.");
}
相关推荐
mit6.8241 小时前
[C# starter-kit] 命令/查询职责分离CQRS | MediatR |
java·数据库·c#
beyond谚语3 小时前
C#学习小笔记(完整版)—— Patience
c#
爱吃小胖橘3 小时前
Unity网络开发--超文本传输协议Http(1)
开发语言·网络·网络协议·http·c#·游戏引擎
IT小农工4 小时前
Word 为每一页设置不同页边距(VBA 宏)
开发语言·c#·word
sali-tec5 小时前
C# 基于halcon的视觉工作流-章42-手动识别文本
开发语言·人工智能·算法·计算机视觉·c#·ocr
咕白m6257 小时前
C# 合并多个PDF文档:高效解决方案
c#·.net
c#上位机9 小时前
wpf之MVVM中只读属性更新界面
c#·wpf·mvvm
技术支持者python,php11 小时前
winform本地上位机-ModbusRTC1.上位机控制台与数据监控(数据监控架构思维与图表系列)
c#
kalvin_y_liu14 小时前
DeploySharp开源发布:让C#部署深度学习模型更加简单
深度学习·开源·c#
c#上位机14 小时前
wpf之GroupBox
c#·wpf