Files
XCEngine/docs/api/XCEngine/Scripting/Mono/MonoScriptRuntime/TryGetClassFieldDefaultValues.md

2.9 KiB
Raw Blame History

MonoScriptRuntime::TryGetClassFieldDefaultValues

命名空间: XCEngine::Scripting

类型: method

头文件: XCEngine/Scripting/Mono/MonoScriptRuntime.h

签名

bool TryGetClassFieldDefaultValues(
    const std::string& assemblyName,
    const std::string& namespaceName,
    const std::string& className,
    std::vector<ScriptFieldDefaultValue>& outFields) const override;

作用

返回指定脚本类当前字段模型中各字段的真实默认值。

这里的“默认值”不是简单的语言零值,而是 C# 字段初始化和默认构造执行后的结果。

当前实现流程

  1. 清空 outFields
  2. 查找类缓存;找不到则返回 false
  3. 切换到当前 app domain。
  4. 创建一个临时托管对象。
  5. 执行默认初始化。
  6. 遍历字段缓存,逐个读取字段值并填充 ScriptFieldDefaultValue
  7. fieldName 排序后返回。

如果任何一步失败,当前实现会清空输出并返回 false

它读取的是哪一批字段

这个方法不会自行重新筛字段,而是复用 TryGetClassFieldMetadata 所对应的同一批字段集合。

因此它同样支持:

  • public 实例字段
  • [SerializeField] private 字段

并同样排除:

  • static
  • const / literal
  • readonly / init-only
  • 未标注的 private
  • 不支持的字段类型

为什么它比“零值表”更有意义

因为它真的构造了一个托管对象,所以能反映:

  • C# 字段初始化表达式
  • 枚举默认值
  • string.Empty
  • 布尔或数值的自定义初始值

例如当前测试直接验证了:

  • FieldMetadataProbe.State 的默认值是 2
  • FieldMetadataProbe.HiddenFlag 的默认值是 true
  • ProjectScriptProbe.Label 的默认值是 "ProjectScriptProbe"
  • ProjectScriptProbe.Speed 的默认值是 2.5f

这也是商业引擎里常见的设计Inspector 默认值和运行时实例的首帧初值,都应来自同一份真实脚本初始化结果。

[SerializeField] private 的默认值也会被读到

这一点很重要。既然 [SerializeField] private 已经进入字段模型,它的默认值也应和 public 字段一样被查询到。

当前测试 ClassFieldDefaultValueQueryReturnsSerializeFieldPrivateInitializers 已经明确验证:FieldMetadataProbe.HiddenFlag 会以 true 返回。

返回值语义

  • true
    • 类存在,且全部字段默认值都成功读取。
  • false
    • 类不存在、临时对象创建失败,或任意字段读取失败。

失败时 outFields 会被清空,调用方不应读取旧内容。

相关文档