C# is和as运算符性能 C# is和as哪个更快

来源:这里教程网 时间:2026-02-21 17:41:38 作者:

is 和 as 在 IL 层面的本质区别

is
运算符只做类型检查,返回
bool
as
运算符尝试转换,成功返回目标引用,失败返回
null
(对引用类型)或
default(T)
(对可空值类型)。两者在 IL 中都调用
isinst
指令,但
as
多一步赋值操作——这步开销极小,几乎可忽略。

连续使用 is + 强制转换时性能更差

常见反模式:

if (obj is string) { var s = (string)obj; ... }
。这会触发两次类型检查:一次
is
,一次强制转换中的隐式
isinst
。JIT 通常不会优化掉第二次检查。

正确写法是直接用
as
var s = obj as string; if (s != null) { ... }
对值类型(如
int?
)需注意:
as
不支持非可空值类型,只能用于引用类型或可空值类型
如果后续必须用非空值类型,且已知安全,可用
obj as string ?? throw new InvalidOperationException()
,避免重复检查

as 在热路径中略快,但差异通常不构成瓶颈

单次调用下,

as
is
+ 强转快约 10%–15%(实测 .NET 6+ x64),因为省去一次运行时类型验证。但这个差距只有在每秒百万级类型判断时才可能被观测到。

真实业务代码中,类型检查往往不是热点,IO、内存分配、锁竞争才是瓶颈 过度纠结
is
vs
as
的微秒级差异,不如检查是否误用了装箱(比如对
int
频繁
is object
使用
as
时务必判空,否则可能引入
NullReferenceException
,调试成本远高于那几纳秒

pattern matching(C# 7+)改变了权衡逻辑

现代 C# 推荐用模式匹配替代裸

is
as
,例如
if (obj is string s) { /* s 已声明且非 null */ }
。它在语义上等价于
as
+ 判空,但由编译器生成更紧凑的 IL,且变量作用域清晰。

这种写法既安全又高效,JIT 可对其做更好优化 对继承链深的对象,
is Type t
as Type
性能表现一致,都依赖 CLR 的类型系统缓存
注意:模式匹配在结构体上会产生复制,若类型较大(如含数组字段),
as
(仅适用引用类型)反而更轻量

实际编码中,优先选语义清晰的写法,而不是预设“哪个更快”。真正影响性能的,往往是类型检查发生的次数和上下文,而不是运算符本身。

相关推荐