# MonoScriptRuntime::TryGetClassFieldDefaultValues **命名空间**: `XCEngine::Scripting` **类型**: `method` **头文件**: `XCEngine/Scripting/Mono/MonoScriptRuntime.h` ## 签名 ```cpp bool TryGetClassFieldDefaultValues( const std::string& assemblyName, const std::string& namespaceName, const std::string& className, std::vector& outFields) const override; ``` ## 作用 返回指定脚本类当前字段模型中各字段的真实默认值。 这里的“默认值”不是简单的语言零值,而是 C# 字段初始化和默认构造执行后的结果。 ## 当前实现流程 1. 清空 `outFields`。 2. 查找类缓存;找不到则返回 `false`。 3. 切换到当前 app domain。 4. 创建一个临时托管对象。 5. 执行默认初始化。 6. 遍历字段缓存,逐个读取字段值并填充 `ScriptFieldDefaultValue`。 7. 按 `fieldName` 排序后返回。 如果任何一步失败,当前实现会清空输出并返回 `false`。 ## 它读取的是哪一批字段 这个方法不会自行重新筛字段,而是复用 [TryGetClassFieldMetadata](TryGetClassFieldMetadata.md) 所对应的同一批字段集合。 因此它同样支持: - `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` 会被清空,调用方不应读取旧内容。 ## 相关文档 - [MonoScriptRuntime](MonoScriptRuntime.md) - [TryGetClassFieldMetadata](TryGetClassFieldMetadata.md) - [Project Script Assembly And Field Sync](../../../../_guides/Scripting/Project-Script-Assembly-And-Field-Sync.md) - [Scripting Runtime And Field Model](../../../../_guides/Scripting/Scripting-Runtime-And-Field-Model.md)