目录

C# 中的 is 关键字详解

is 运算符是 C# 中用于类型检查模式匹配的重要工具。它允许你在运行时检查一个对象是否与特定的类型兼容,或者是否符合某种特定的模式。

1. 基础用法:类型检查

在 C# 7.0 之前,`is` 主要用于检查一个对象实例是否属于某个特定的类型(或者该类型的派生类,或者是实现了该接口的类)。

语法:

expression is type

返回值:

示例:

object obj = "Hello World";
 
if (obj is string)
{
    Console.WriteLine("obj 是一个字符串");
}
else
{
    Console.WriteLine("obj 不是一个字符串");
}

2. 模式匹配 (C# 7.0 及更高版本)

从 C# 7.0 开始,`is` 运算符的功能得到了极大的增强,引入了模式匹配 (Pattern Matching)。这使得我们可以不仅检查类型,还能在检查成功的同时声明一个新的变量。

2.1 声明模式 (Declaration Pattern)

这是最常用的增强功能。它允许你在检查类型的同时,将转换后的结果赋值给一个新变量。

语法:

expression is Type variableName

示例:

object obj = 123;
 
// 以前的写法(需要两步):
// if (obj is int) { int i = (int)obj; ... }
 
// 现在的写法(一步到位):
if (obj is int i)
{
    // 这里的 i 是 int 类型,且已经赋值
    Console.WriteLine($"这是一个整数: {i}");
    Console.WriteLine($"整数的平方: {i * i}");
}

2.2 常量模式 (Constant Pattern)

你可以使用 `is` 来检查表达式是否等于某个常量值(包括 `null`)。

示例:

object obj = null;
 
if (obj is null)
{
    Console.WriteLine("对象是 null");
}
 
int number = 5;
if (number is 5)
{
    Console.WriteLine("数字是 5");
}

2.3 var 模式

`var` 模式总是匹配成功,并将结果赋值给变量。这在需要创建临时变量或者配合 `switch` 表达式时很有用。

if (GetResult() is var result)
{
    // result 包含了 GetResult() 的返回值
    // 即使返回 null,这里也会进入,result 为 null
    Console.WriteLine($"结果是: {result}");
}

3. 进阶模式匹配 (C# 9.0 及更高版本)

C# 9.0 引入了更多的逻辑模式,使得 `is` 表达式更加强大,读起来更像自然语言。

3.1 逻辑模式 (not, and, or)

你可以组合多个模式。

示例:

object obj = "Test";
 
// 检查不是 null
if (obj is not null)
{
    Console.WriteLine("对象不为空");
}
 
// 检查是否为字符串且不为空
if (obj is string s and not "")
{
    Console.WriteLine($"非空字符串: {s}");
}
 
int age = 25;
// 范围检查 (C# 9.0+)
if (age is >= 18 and <= 60)
{
    Console.WriteLine("年龄在 18 到 60 之间");
}

4. is 运算符 vs as 运算符

C# 中还有一个 `as` 运算符,也用于类型转换。了解它们的区别很重要。

特性 is 运算符 as 运算符
功能 检查类型兼容性,返回 bool。 尝试转换类型,返回对象或 null。
失败处理 返回 `false`。 返回 `null`。
适用范围 可用于值类型和引用类型(拆箱/装箱)。 只能用于引用类型或可空值类型。
推荐场景 当你只需要判断,或者配合模式匹配直接使用变量时。 当你只需要转换结果,且不介意结果为 null 时。

对比示例:

object o = "test";
 
// 使用 is (推荐)
if (o is string s)
{
    Console.WriteLine(s.Length);
}
 
// 使用 as
string s2 = o as string;
if (s2 != null)
{
    Console.WriteLine(s2.Length);
}

5. 总结

最佳实践建议: 尽量使用 声明模式 (`if (obj is Type variable)`) 代替旧的 `is` 检查加强制转换,这样代码更简洁、性能更好(只进行一次类型检查)。