You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C#存储声明和类型模式结果会触发CS0165未赋值变量错误?

C#模式匹配中未赋值变量报错及简洁写法问题

问题描述

我好奇为何以下两段代码都会触发错误CS0165: 使用未赋值的局部变量'i':

// Attempt #1
object obj = 4;
bool isInt = obj is int i;
if (isInt)
    Console.WriteLine("obj = {0}", i); // CS0165

// Attempt #2
object obj = 4;
bool isInt;
if (isInt = obj is int i)
    Console.WriteLine("obj = {0}", i); // CS0165

以下代码可以编译,但似乎没必要这么写:

object obj = 4;
bool isInt = false;
if (obj is int i)
{
    isInt = true;
    Console.WriteLine("obj = {0}", i);
}

在使用C#声明和类型模式时,有没有更简洁的方式存储测试条件的结果?


问题解答

报错原因

你遇到的CS0165错误,核心在于C#编译器的流分析规则:它不会跟踪普通布尔变量(比如isInt)和模式匹配变量(比如i)之间的依赖关系。

  • 对于Attempt #1:你把obj is int i的结果存入isInt后再判断分支,但编译器不会将“isInt为true”和“i已赋值”这两个逻辑关联起来。它只认可直接将obj is int i写在if条件中的场景——只有这时编译器能100%确定进入分支时i已完成赋值。
  • Attempt #2同理:即便你把模式匹配结果赋值给isInt后再做判断,编译器依然不会通过isInt的布尔值推断i的赋值状态,因此仍会报错。

简洁解决方案

如果既要保存类型检查的结果,又要合法使用模式变量i,推荐两种简洁且合规的写法:

方案一:分支内赋值结果(直观清晰)

这是最符合代码可读性要求的写法,逻辑明确,编译器完全认可:

object obj = 4;
bool isInt = false;
if (obj is int i)
{
    isInt = true;
    Console.WriteLine("obj = {0}", i);
}
// 后续可正常使用isInt变量

这种写法并不冗余——毕竟你需要同时实现“保存检查结果”和“使用匹配后变量”两个需求,这是最直接的实现方式。

方案二:紧凑式赋值+判断(代码更短)

如果追求代码紧凑,可以借助逻辑运算符让编译器认可i的赋值状态:

object obj = 4;
bool isInt;
if ((isInt = obj is int i) && i is int)
{
    Console.WriteLine("obj = {0}", i);
}

这里的i is int是冗余的类型检查,但它能触发编译器的流分析,确认进入分支时i已赋值,同时完成isInt的赋值。不过这种写法可读性稍弱,不如方案一直观。

另外补充:如果后续不需要使用isInt变量,直接写if (obj is int i)并在分支内使用i即可,这是最简洁的模式匹配写法。


内容的提问来源于stack exchange,提问作者Jeff G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:45:30