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

为何C#中定义在不同程序集的struct未初始化使用编译结果不同

问题原因

C#编译器对结构类型的明确赋值检查规则,会根据结构是否定义在当前编译的程序集内发生差异:

  • 当MetaWorkspace定义在当前程序集时
    你声明的public string Name { get; set; }这类自动实现属性,编译器会为其生成私有的隐藏后备字段。此时编译器能看到结构的所有实例字段(包括私有后备字段),根据明确赋值规则,你必须要么调用结构的构造函数完成初始化,要么给所有实例字段逐一赋值,才能访问结构的实例成员(包括属性的setter)。
    你代码里只声明了MetaWorkspace ws;没有调用构造函数,也没法访问私有后备字段直接赋值,所以当你尝试调用ws.Id的setter时,编译器判定ws未完成明确赋值,抛出CS0165错误。
  • 当MetaWorkspace定义在外部引用的程序集时
    编译器无法访问外部程序集里结构的私有成员,也就看不到自动属性对应的私有后备字段。此时编译器判定结构明确赋值的标准,仅检查你是否给所有可访问的实例字段完成了赋值。如果结构没有公开的实例字段(你的例子里只有公开属性,没有公开字段),编译器会默认该结构只要完成声明就算已明确赋值,所以你可以直接调用属性的setter,代码正常编译。
行为合法性说明

这种写法不属于未定义行为:
C#运行时会保证所有值类型的实例都完成零初始化,哪怕你没有显式调用构造函数,局部结构变量在栈上分配时也会被默认清零,所有字段都处于默认值状态(引用类型字段为null,值类型字段为对应零值)。你后续给Id赋值的操作是完全合法的,最终得到的是符合结构定义的正常对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:48:05