Skip to content

API Host INativeTypedDocument

Liu.Yandong.Hanks edited this page Sep 7, 2026 · 6 revisions

INativeTypedDocument

NativeType 参与 TDoc 的读写契约。

命名空间:AuroraScript.Runtime.Serialization。种类:interface。适用于 4.0.0。

返回 .NET Host API 参考 · 脚本原生类型 · Typed Document

概述

在 [NativeType] 的 ScriptObject 实例类型上实现本接口,并把类型列入 CompilerOptionsBuilder.WithNativeTypes。脚本 tdoc Vec2 { ... } / tdoc Vec2 [ ... ] / tdoc Flag false 以及宿主 TDoc.parse / TDoc.stringify 会直接构造该 NativeType,而不是 ClrInstanceObject。

类型名前缀来自 [NativeType],经引擎 catalog 解析。构造由 NativeType 生成器补上:无用户构造函数时生成无参构造,否则生成 CreateTypedDocument()。仅当空实例需要额外初始化时才手写该工厂。

下面的类型只导出原生字段,因此不生成 NativePrototype。如果同一类型还导出普通实例方法,用户编写的每个构造函数必须显式调用 base(NativePrototype);生成器创建的 TDoc 构造路径会自动使用该原型。

[NativeType("Vec2")]
public sealed partial class Vec2 : ScriptObject, INativeTypedDocument
{
    [Export("x")] public double X;
    [Export("y")] public double Y;

    [Export]
    public Vec2(double x, double y)
    {
        X = x;
        Y = y;
    }

    public void WriteTypedDocument(ref TypedDocumentOutput output)
    {
        output.WriteElement(X);
        output.WriteElement(Y);
    }

    public void ReadTypedDocument(ref TypedDocumentInput input)
    {
        if (input.IsElement)
        {
            switch (input.ElementIndex)
            {
                case 0: X = input.Value.Number; return;
                case 1: Y = input.Value.Number; return;
                default: throw input.Error("Vec2 requires two numbers.");
            }
        }

        switch (input.MemberName)
        {
            case "x": X = input.Value.Number; return;
            case "y": Y = input.Value.Number; return;
            default: throw input.Error("Unknown Vec2 member.");
        }
    }
}

标量形态用 WriteValue:

[NativeType("Flag")]
public sealed partial class Flag : ScriptObject, INativeTypedDocument
{
    [Export("value")] public bool Value;

    [Export]
    public Flag(bool value) => Value = value;

    public void WriteTypedDocument(ref TypedDocumentOutput output) =>
        output.WriteValue(Value);

    public void ReadTypedDocument(ref TypedDocumentInput input)
    {
        if (input.IsValue)
        {
            Value = input.Value.Boolean;
            return;
        }

        if (input.IsMember && input.MemberName == "value")
        {
            Value = input.Value.Boolean;
            return;
        }

        throw input.Error("Flag requires a boolean value.");
    }
}

方法

WriteTypedDocument

void WriteTypedDocument(ref TypedDocumentOutput output)

把当前实例写成 TDoc 对象体、数组体或标量体。第一次 WriteMember 锁定对象形态(Vec2 {x 3,y 4});第一次 WriteElement 锁定数组形态(Vec2 [3,4]);第一次 WriteValue 锁定标量形态(User "a,b,c"、State 1、Flag false)。同一次写入不要混用。WriteValue 只接受 null、boolean、number、string。

ReadTypedDocument

void ReadTypedDocument(ref TypedDocumentInput input)

读取一个已解析的对象成员、数组元素或标量值。用 IsMember / IsElement / IsValue、MemberName / ElementIndex 和 Value。非法名字、下标或 readonly 应抛出 TypedDocumentException,可用 input.Error(message)。

动态属性

动态 ScriptObject 属性默认不属于 TDoc 契约,由每个 NativeType 自己决定是否支持。对象体实现可以在固定字段之后调用:

public void WriteTypedDocument(ref TypedDocumentOutput output)
{
    output.WriteMember("name", Name);
    output.WriteDynamicMembers(this);
}

public void ReadTypedDocument(ref TypedDocumentInput input)
{
    if (input.IsMember && input.MemberName == "name")
    {
        Name = input.Value.StringText;
        return;
    }

    input.DefineDynamicMember(this);
}

两个辅助方法保留动态成员的可枚举与 readonly 语义。数组体、标量体没有命名成员,不能使用 WriteDynamicMembers。JSON.stringify 不使用 TDoc 契约,会自动包含可枚举 Native 字段与动态属性。

相关 API

AuroraScript.JIT 4.0.0

入门

语言

脚本 API

宿主集成

工具

项目

Clone this wiki locally