跳到主要内容

返回值门面类型

默认返回值按 声明类型 挂门面;标注 LuaMarshalType.ActualTypeUserData 后,仍是 ByObj userdata,但 门面 = 运行时实际类型,从而在 Lua 可见派生类成员。权威细则:02-MARSHAL-AS、06-CLASS。

为何需要 ActualTypeUserData​

Lua 侧访问成员靠的是 userdata 挂接的 门面(view),不是「猜运行时真实类型」。默认 Push 时门面 = 方法/属性声明的返回类型,即使堆上实例更具体也 不会 自动换成派生类:

Base Create() => new Child(); // 实际是 Child,Lua 门面仍是 Base
local o = factory:Create()
o:BaseOnly() -- OK:门面 Base 上有
-- o.childField -- 失败:门面看不到 Child 独有成员

默认故意按声明类型出门面,避免:

风险说明
同一次调用「类型飘忽」脚本无法假定返回值总是某固定 API 面
与特殊 Marshal 纠缠如声明为 object 时,实际是 string 也不应默默变成 Lua string
成员表膨胀按声明类型 Bind 的 IMT 可预测、可缓存

因此只有在 API 声明偏宽(基类 / 接口 / Component / object),而脚本几乎总要调派生成员 时,才值得在返回值上标 ActualTypeUserData,让门面 = obj.GetType(),少写一遍 zlua.cast。

典型需要:

场景声明返回实际常见不标时的痛点
工厂 / 多态创建Base / 接口具体 Child每次 cast 才能调派生成员
Unity GetComponentComponent / 接口Button 等只能当声明类型用,或脚本侧 zlua.cast。可改用总开关 Unity 优化
返回 object / 装箱宽类型object具体 class门面永远是 System.Object

不需要 的情况:声明类型已经覆盖你会调用的成员;或偶发才 downcast(用 zlua.cast 即可)。

默认 vs ActualType​

默认 PushActualTypeUserData
形态ByObj仍是 ByObj
门面声明类型实际类型
典型CreateChild() → BaseCreateChildActual() → Child
Base CreateChild() => new Child();

[return: LuaMarshalAs(LuaMarshalType.ActualTypeUserData)]
Base CreateChildActual() => new Child();
local o = ObjectFactory.CreateChild() -- 门面 Base
local c = zlua.cast(o, Child) -- 脚本侧改门面
local a = ObjectFactory.CreateChildActual() -- 返回时门面已是 Child

怎么标​

方式说明
Attribute[return: LuaMarshalAs(LuaMarshalType.ActualTypeUserData)]
XMLReturn=ActualTypeUserData(挂在声明类型;继承可用)
热更新程序集只能 Attribute,不支持 XML

仅返回值。标在参数 / 字段 / 属性 / 类型级 → 非法(Mono Attribute:回退 Default + 日志;Il2Cpp Generate / XML:可失败)。

合法类型(摘要)​

适用于默认走 ByObj 的托管引用类型:class / interface / object / 数组等。

不可用于普通 struct、默认非 ByObj 的 string 等。完整合法集合见 02-MARSHAL-AS §3。

与 zlua.cast 互补​

ActualTypeUserDatazlua.cast
谁改门面C# 返回时自动Lua 脚本主动
适用固定 API 想「按真类型出门」偶发 downcast

与泛型方法​

如 GetComponent 闭合后声明返回 Component,可在开放方法返回槽标 ActualType;闭合后按 实际组件类型 出门面。见 泛型。

常见误解​

误解实际
会把 string 变成 Lua string否;实际为 string 时仍为 ByObj(门面 System.String)
改变虚派发语义否;按 view 找槽,再对真实 this 虚调
等于 Opaque / Table否;形态仍是 ByObj UserData

学习路径​

上一篇LuaMarshalAs
下一篇0GC Marshal

相关文档​