C#中is运算符的正确用法
C# 中的is运算符主要用于类型检查和模式匹配。它用于在运行时检查对象的类型返回一个布尔值指示表达式的结果是否与指定的类型兼容或者是否可以转换为该类型。is运算符在类型转换前进行检查可以有效地避免因类型不匹配而导致的InvalidCastException异常 。一、is运算符的基本用法is运算符的基本语法为expression is type。如果expression的结果非空并且可以通过引用转换、装箱转换、拆箱转换或用户定义的隐式/显式转换转换为type类型则结果为true否则为false。场景描述返回值引用转换检查对象是否为特定类或其派生类的实例。true/false装箱/拆箱转换检查值类型与object或接口的兼容性。true/false类型匹配在模式匹配中检查并声明新变量。true并赋值 /false以下是一个基本示例using System; class Animal { } class Dog : Animal { } class Cat : Animal { } class Program { static void Main() { Animal myAnimal new Dog(); // 使用 is 进行类型检查 if (myAnimal is Dog) { Console.WriteLine(myAnimal 是一只 Dog。); } if (myAnimal is Cat) { Console.WriteLine(myAnimal 是一只 Cat。); // 这行不会执行 } else { Console.WriteLine(myAnimal 不是一只 Cat。); } // 检查基类 if (myAnimal is Animal) { Console.WriteLine(myAnimal 是一个 Animal。); // 始终为 true } // 检查 null Animal nullAnimal null; Console.WriteLine(nullAnimal is Animal); // 输出False因为表达式结果为 null } }运行上述代码输出结果为myAnimal 是一只 Dog。 myAnimal 不是一只 Cat。 myAnimal 是一个 Animal。 False二、is运算符与模式匹配C# 7.0 及更高版本从 C# 7.0 开始is运算符的功能得到了极大增强支持声明模式和类型模式可以在检查类型的同时将结果赋值给一个新变量 。using System; class Animal { public string Name { get; set; } } class Dog : Animal { public void Bark() Console.WriteLine(Woof!); } class Cat : Animal { public void Meow() Console.WriteLine(Meow!); } class Program { static void MakeSound(Animal animal) { // 使用 is 进行类型检查和变量声明 if (animal is Dog dog) // 如果 animal 是 Dog 类型则将其赋值给新变量 dog { Console.WriteLine($找到一只狗名字是 {dog.Name}。); dog.Bark(); } else if (animal is Cat cat) // 如果 animal 是 Cat 类型则将其赋值给新变量 cat { Console.WriteLine($找到一只猫名字是 {cat.Name}。); cat.Meow(); } else { Console.WriteLine(未知动物类型。); } } static void Main() { Animal myDog new Dog { Name Buddy }; Animal myCat new Cat { Name Whiskers }; MakeSound(myDog); MakeSound(myCat); } }输出找到一只狗名字是 Buddy。 Woof! 找到一只猫名字是 Whiskers。 Meow!关键点模式匹配中的is表达式animal is Dog dog不仅检查类型还在条件为真时将animal安全地转换为Dog类型并赋值给新变量dog。这个新变量的作用域限定在紧随其后的if语句块内。三、is与as运算符的对比与选择is和as都用于安全的类型转换但目的和行为不同。as运算符尝试进行转换如果失败则返回null而is仅进行检查 。特性is运算符as运算符主要目的类型检查。判断对象是否与给定类型兼容。安全类型转换。尝试将对象转换为指定类型。返回值booltrue或false。目标类型的值转换成功或null转换失败。异常从不抛出异常。从不抛出异常。转换失败时返回null。典型用法在转换前进行条件判断。直接尝试转换并处理可能的null结果。模式匹配支持C# 7.0可同时声明变量。不支持。以下示例展示了如何结合使用is和as以及它们各自适用的场景using System; class Animal { } class Dog : Animal { public void Fetch() Console.WriteLine(Fetching ball...); } class Program { static void ProcessWithIs(Animal animal) { // 使用 is 进行检查然后进行强制转换 if (animal is Dog) { Dog dog (Dog)animal; // 因为已经用 is 检查过所以这里是安全的 dog.Fetch(); } else { Console.WriteLine(不是狗无法执行 Fetch。); } } static void ProcessWithAs(Animal animal) { // 使用 as 进行转换然后检查结果是否为 null Dog dog animal as Dog; if (dog ! null) { dog.Fetch(); } else { Console.WriteLine(不是狗无法执行 Fetch。); } } static void ProcessWithPatternMatching(Animal animal) { // 使用 is 模式匹配最简洁、高效的方式 if (animal is Dog safeDog) // 检查并转换一步完成 { safeDog.Fetch(); } else { Console.WriteLine(不是狗无法执行 Fetch。); } } static void Main() { Animal myDog new Dog(); Animal notADog new Animal(); Console.WriteLine( 使用 is 强制转换 ); ProcessWithIs(myDog); ProcessWithIs(notADog); Console.WriteLine( 使用 as ); ProcessWithAs(myDog); ProcessWithAs(notADog); Console.WriteLine( 使用 is 模式匹配 ); ProcessWithPatternMatching(myDog); ProcessWithPatternMatching(notADog); } }输出 使用 is 强制转换 Fetching ball... 不是狗无法执行 Fetch。 使用 as Fetching ball... 不是狗无法执行 Fetch。 使用 is 模式匹配 Fetching ball... 不是狗无法执行 Fetch。选择建议如果只需要检查类型不进行后续操作使用is例如if (obj is MyType)。如果检查后需要转换为该类型并使用优先使用 C# 7.0 的is模式匹配if (obj is MyType var)因为它最简洁且性能通常更优避免了双重类型检查。如果转换失败时你希望得到一个null值进行其他处理使用as运算符例如var result obj as MyType。避免使用is检查后再用as转换这是一种低效的做法因为进行了两次类型检查。应直接使用模式匹配或as。四、is运算符的其他应用场景检查可空值类型is运算符可以与null字面量一起使用简洁地检查可空值类型是否具有值。int? nullableInt 42; if (nullableInt is int value) // 检查 nullableInt 是否有值并将其赋值给 value { Console.WriteLine($有值: {value}); } else { Console.WriteLine(无值 (null)); } nullableInt null; if (nullableInt is null) // 专门检查是否为 null { Console.WriteLine(它是 null。); }常量模式检查表达式结果是否等于指定的常量值。object input 100; if (input is 100) { Console.WriteLine(输入等于 100。); }与switch语句/表达式结合在switch中is模式匹配可以非常强大地处理多种类型。static string DescribeShape(object shape) { return shape switch { Circle c $圆形半径 {c.Radius}, Rectangle r $矩形长 {r.Length} 宽 {r.Width}, Triangle t $三角形, null 未提供形状, _ 未知形状 // 默认情况 }; }五、性能与最佳实践性能is运算符的类型检查是高效的运行时操作。模式匹配版本的is在性能上通常优于先is后强制转换的方式因为它避免了重复的类型判断 。可读性使用is模式匹配 (if (obj is MyType var)) 可以极大地提高代码的可读性和简洁性是推荐的现代 C# 写法。避免异常始终使用is或as来替代直接的强制转换(Type)obj除非你百分之百确定对象的类型。直接的强制转换在失败时会抛出InvalidCastException而is和as提供了安全的替代方案 。总之is运算符是 C# 中进行安全类型检查和模式匹配的核心工具。从基本的类型兼容性判断到现代的模式匹配语法它帮助开发者编写出更安全、更清晰、更健壮的代码。参考来源C#中的is和as运算符C#中as和is关键字作用使用 as 和 is 运算符安全地进行强制转换【C#】尝试类型转换异常System.InvalidCastException: Specified cast is not valid.解决方案c# is / as 实例C#--运算符