====== C# 中的 is 关键字详解 ======
**is** 运算符是 C# 中用于**类型检查**和**模式匹配**的重要工具。它允许你在运行时检查一个对象是否与特定的类型兼容,或者是否符合某种特定的模式。
===== 1. 基础用法:类型检查 =====
在 C# 7.0 之前,`is` 主要用于检查一个对象实例是否属于某个特定的类型(或者该类型的派生类,或者是实现了该接口的类)。
**语法:**
expression is type
**返回值:**
* 如果表达式的结果不为 null 且可以转换为该类型,返回 `true`。
* 否则,返回 `false`。
**示例:**
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) ====
你可以组合多个模式。
* **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. 总结 =====
* **基础**: `is` 用于检查运行时类型。
* **进化**: 结合模式匹配,`is` 可以同时完成“检查”和“赋值”两项工作。
* **逻辑**: 使用 `and`, `or`, `not` 可以编写非常具有表现力的条件判断代码。
**最佳实践建议:**
尽量使用 **声明模式** (`if (obj is Type variable)`) 代替旧的 `is` 检查加强制转换,这样代码更简洁、性能更好(只进行一次类型检查)。