c# is 和 as 操作符的区别

发布时间 - 2026-01-05 00:00:00    点击率:
is只判断类型不转换,as尝试转换失败返回null;二者组合使用会导致重复类型检查,C# 7+推荐用模式匹配if(obj is string s)一次性完成判断与赋值。

is 操作符只判断类型,不转换

is 用于运行时检查对象是否属于某个类型(或其派生类型),返回 truefalse,**不会执行任何类型转换**。它不抛异常,也不改变原变量值。

常见错误是以为 is 后能直接用转型结果:

if (obj is string) {
    Console.WriteLine(obj.Length); // 编译错误!obj 还是 object 类型
}

正确写法必须显式转换(或用模式匹配):

  • 老写法:if (obj is string) { string s = (string)obj; ... }
  • C# 7+ 推荐:if (obj is string s) { Console.WriteLine(s.Length); } —— 这里 s 是新声明的局部变量,不是 obj 被“改类型”了

as 操作符尝试转换,失败返回 null

as 尝试将对象引用转换为指定引用类型或可空类型。**仅适用于引用类型和可空值类型**;对非可空值类型(如 intDateTime)使用会编译报错。

它不抛异常,转换失败时返回 null(对可空值类型返回 null 值)。但要注意:如果目标类型是 stringobject 等引用类型,源为 null 时也返回 null,无法区分“本来就是 null”和“转换失败”。

  • 合法:var s = obj as string;objobject
  • 非法:var i = obj as int; → 编译错误,int 是非可空值类型
  • 合法(可空):var i = obj as int?;

is 和 as 组合使用容易引发两次类型检查

这是性能和可读性上最常被忽略的问题。下面这段代码效率低且冗余:

if (obj is string) {
    string s = obj as string; // 又做了一次运行时类型检查
    Process(s);
}

CLR 在 isas 中都会执行相同的类型判定逻辑,相当于重复工作。C# 7+ 的模式匹配语法正是为解决这个而生:

  • ✅ 推荐:if (obj is string s) Process(s); —— 一次检查,一次赋值
  • ✅ 或者直接用 as + 空检查:string s = obj as string; if (s != null) Process(s);
  • ❌ 避免 is 后紧跟 as,除非你明确需要中间的布尔判断逻辑

值类型场景下 as 完全不可用,is 仍可用

对值类型(如 intGuid、自定义 struct),as 不能用,编译器直接拒绝。但 is 可以配合装箱/拆箱判断:

object obj = 42;
if (obj is int) { /* true */ }
// var x = obj as int; // 编译错误

若要安全获取值类型,只能用 is + 显式拆箱,或用泛型方法(如 Convert.ChangeType);注意拆箱必须类型完全一致,obj is int 成立不代表 (int)obj 一定成功(比如 objlong 装箱的 42,is intfalse,但有人误以为可以强转)。

真正容易被忽略的是:is 对值类型的判断本质是“是否为该类型装箱后的对象”,它不支持隐式转换检查(比如 longint),这点和 as 的适用范围限制一起,让值类型的安全转换始终比引用类型更繁琐。


# 区别  # c#  # 编译错误  # 隐式转换  # String  # Object  # NULL  # if  # 派生类型  # 局部变量  # int  # 值类型  # 引用类型  # 空类型  # Length  # Struct  # 泛型  # var  # 类型转换  # console  # 对象  # 它不  # 或用  # 的是  # 这是  # 也不  # 两次  # 适用于  # 不代表  # 这段  # 布尔 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  零基础网站服务器架设实战:轻量应用与域名解析配置指南  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  如何彻底卸载建站之星软件?  香港服务器租用费用高吗?如何避免常见误区?  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  Laravel怎么使用artisan命令缓存配置和视图  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  无锡营销型网站制作公司,无锡网选车牌流程?  Python制作简易注册登录系统  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  如何快速启动建站代理加盟业务?  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  详解Android图表 MPAndroidChart折线图  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  在线制作视频的网站有哪些,电脑如何制作视频短片?  如何用已有域名快速搭建网站?  如何在阿里云ECS服务器部署织梦CMS网站?  太平洋网站制作公司,网络用语太平洋是什么意思?  bing浏览器学术搜索入口_bing学术文献检索地址  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  Laravel怎么连接多个数据库_Laravel多数据库连接配置  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  PHP 500报错的快速解决方法  canvas 画布在主流浏览器中的尺寸限制详细介绍  Laravel如何自定义错误页面(404, 500)?(代码示例)  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  Laravel如何生成API文档?(Swagger/OpenAPI教程)  Python结构化数据采集_字段抽取解析【教程】  香港服务器如何优化才能显著提升网站加载速度?  javascript中的try catch异常捕获机制用法分析  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Android实现代码画虚线边框背景效果  如何快速查询域名建站关键信息?  Laravel怎么使用Intervention Image库处理图片上传和缩放  如何用腾讯建站主机快速创建免费网站?  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  如何用5美元大硬盘VPS安全高效搭建个人网站?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】