当前位置: 首页 > news >正文

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语句块内。

三、isas运算符的对比与选择

isas都用于安全的类型转换,但目的和行为不同。as运算符尝试进行转换,如果失败则返回null,而is仅进行检查 。

特性is运算符as运算符
主要目的类型检查。判断对象是否与给定类型兼容。安全类型转换。尝试将对象转换为指定类型。
返回值booltruefalse)。目标类型的值(转换成功)或null(转换失败)。
异常从不抛出异常从不抛出异常。转换失败时返回null
典型用法在转换前进行条件判断。直接尝试转换,并处理可能的null结果。
模式匹配支持(C# 7.0+),可同时声明变量。不支持。

以下示例展示了如何结合使用isas,以及它们各自适用的场景:

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。

选择建议

  1. 如果只需要检查类型,不进行后续操作:使用is(例如if (obj is MyType))。
  2. 如果检查后需要转换为该类型并使用优先使用 C# 7.0 的is模式匹配if (obj is MyType var)),因为它最简洁且性能通常更优(避免了双重类型检查)。
  3. 如果转换失败时你希望得到一个null值进行其他处理:使用as运算符(例如var result = obj as MyType)。
  4. 避免使用is检查后再用as转换:这是一种低效的做法,因为进行了两次类型检查。应直接使用模式匹配或as

四、is运算符的其他应用场景

  1. 检查可空值类型
    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。"); }
  2. 常量模式
    检查表达式结果是否等于指定的常量值。

    object input = 100; if (input is 100) { Console.WriteLine("输入等于 100。"); }
  3. 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,而isas提供了安全的替代方案 。

总之,is运算符是 C# 中进行安全类型检查和模式匹配的核心工具。从基本的类型兼容性判断到现代的模式匹配语法,它帮助开发者编写出更安全、更清晰、更健壮的代码。


参考来源

  • C#中的is和as运算符
  • C#中as和is关键字作用
  • 使用 as 和 is 运算符安全地进行强制转换
  • 【C#】尝试类型转换异常System.InvalidCastException: Specified cast is not valid.解决方案
  • c# is / as 实例
  • C#--运算符
http://www.zskr.cn/news/1388171.html

相关文章:

  • 如何选择适合的光谱仪?专家教你三步选型法
  • 惊了!输入主题,这几款AI论文软件直接生成结构完整的毕业论文
  • 【开发日记】——在线程中使用容器崩溃问题
  • 打破国外垄断,对标国际顶尖水平——国产七位半数字多用表AMC93200的技术突围之路
  • ps去除图片中文字
  • S3 Files深度解析:对象存储与文件系统的桥梁,AI/ML数据工作流新范式
  • SM2850P输出5V紧凑型离线式、无电感交流输入线性稳压器芯片解析
  • 树莓派零代码实现物理开关机:设备树覆盖与MOS管电路详解
  • 数字孪生落地实践:如视案例解读|从实景三维重建到园区、工厂、油田和展陈应用
  • ncmdump终极指南:三步解锁网易云音乐加密NCM文件
  • C#从零开始学习笔记---第十一天
  • HybridCLR:Unity全平台C#热更新的原生级完整解决方案
  • U-Boot 移植(2)
  • 系统集成中的诚实失败:推理日志如何揭示隐藏的认知偏差
  • 加抑制剂润滑油氧化安定性测定仪:原理、结构与技术参数解析
  • 从零构建多智能体框架:基于“片场”模型的设计与实战
  • 2026年崇左市正规上门黄金白银回收品牌门店名录 K金+铂金+金条+银条回收门店联系方式推荐+指南 - 盛世金银回收
  • AI Agent 完全拆解:从原理到架构到实战,一次讲透(3)
  • AI+Obsidian进阶玩法,自动把播客视频变成可搜索的永久知识库
  • Rails AI后台任务优化:智能重试、速率限制与死信队列实战
  • 算法公平性:群体公平与个体公平的权衡与融合技术实践
  • 自动剪辑哪个更省事?5款实测对比不翻车:日更矩阵如何批量混剪不撞车
  • Java 高频八股:静态、成员、内部类,一篇文章全搞定,99%小白搞不清
  • Lindy效应如何重塑营销自动化:3个被低估的“时间验证指标”正在淘汰83%的传统工作流
  • 72小时极限压测PlayAI语音引擎:超时丢帧、语调塌陷、跨语言混读错误率飙升——这份报告可能改变你的TTS选型决策
  • MCP安全漏洞深度解析:命令注入与SSRF的2026年防御实战
  • 2026年保定市本地上门黄金回收门店指南 彩金+铂金+金条+白银回收门店联系方式推荐 - 大熊猫898989
  • 安卓6老设备救星:手把手教你用Termux v0.79离线版跑起Linux(附避坑源配置)
  • Linux系统中用户锁定后如何解锁
  • 在线PDF工具真免费评测:iLovePDF如何通过五大维度考验