值类型
enum、struct、Nullable<T> 均为值类型相关形态。行为以 Struct Marshal、Enum Marshal 为准。
需要 Table / UnpackedValues / Opaque 等少分配套路时,见 LuaMarshalAs、0GC Marshal。
形态对照
| 类型 | 默认跨边界形态 | 构造实例 |
|---|---|---|
| enum | integer / number(常量) | 无 EnumType(...) / _ctor;boxed 仅用 zlua.box |
| struct | ByValUserData 等(见规范) | Type(...) / _default() |
| Nullable<T> | 有值同 T;无值 → Lua nil | — |
默认 不能 用 { X=1, Y=2 } 或 foo(x, y) 组装 struct 传入 C#,须 Type(...) / ByVal userdata,或显式 [LuaMarshalAs(Table|UnpackedValues)](见上)。
enum
跨边界默认就是 integer / number(类型表上的常量也是整型,不是 userdata):
local Color = CSharp.AC['MyGame.Color']
print(Color.Red) -- 整型值,非 userdata
host:SetColor(Color.Red)
host:SetColor(1) -- underlying 整型亦可
比较常量时用 integer,不要当 userdata 比。类型表 无 __call,不要写 Color(...) / Color._ctor(...)。
需要 boxed 枚举对象(如部分 object 形参、数组槽位等)时,只用 zlua.box:
local boxed = zlua.box(Color, Color.Red)
local boxed2 = zlua.box(Color, 2)
print(zlua.unbox(boxed)) -- underlying integer
细则见 Enum Marshal。
struct
local Point2D = CSharp.AC['MyGame.Point2D']
local origin = Point2D._default()
local p = Point2D(3, 4)
p.X = 10
p.Y = 20
| 传递 | C# 形参 | 行为 |
|---|---|---|
userdata(如 Point2D(...)) | by-val Point2D | 拷贝 |
| userdata(同型) | ref / out / in Point2D | 真 ref,可写回 |
静态成员经类型表访问;struct 无继承。ref struct 不作普通 by-val。
Nullable<T>
- C#
null(无值)↔ Luanil - 有值时按底层
T的规则 Marshal - 不要给非 Nullable 的值类型传
nil
完整示例(示意)
namespace MyGame
{
public enum Team { None = 0, Red = 1, Blue = 2 }
public struct Vec2
{
public float X, Y;
public Vec2(float x, float y) { X = x; Y = y; }
public static float Dot(Vec2 a, Vec2 b) => a.X * b.X + a.Y * b.Y;
}
}
local Team = CSharp.AC['MyGame.Team']
local Vec2 = CSharp.AC['MyGame.Vec2']
print(Team.Red)
print(Vec2.Dot(Vec2(1, 0), Vec2(0, 1)))
常见错误
| 现象 | 处理 |
|---|---|
| enum 当 userdata 比较失败 | 用 integer 比较 |
Color(...) / Color._ctor 失败 | enum 无类型表构造;传整型,或 zlua.box |
| struct 修改未回写 | by-val 拷贝;对 ref 形参传入同型 userdata(Type(...))或走 Opaque |
{X=,Y=} 传入未标注的 struct | 标 Table(见 LuaMarshalAs),或先 Type(...) |
foo(x,y) 传入未标注的 struct | 标 UnpackedValues(见 0GC Marshal) |
ref struct 作 by-val | 不支持 |
学习路径
| 上一篇 | C# 调用 Lua |
| 下一篇 | Function 与 Delegate |