跳到主要内容

Lua 调用 C#

通过全局 CSharp 根表访问 public 类型与成员。语义贴近 C#:Type() 构造、obj:Method() 调实例方法、静态走类型表。含 namespace 须括号键。

Canonical:app.lua、Demo.cs

同名多签名的解析见 方法重载(本章末有预告)。

1. 访问类型​

CSharp
└─ Assembly-CSharp
└─ Demo
└─ ['MyGame.UI.Panel']
CSharp['AC'] = CSharp['Assembly-CSharp'] -- 推荐短别名

local Demo = CSharp.AC.Demo
local Panel = CSharp.AC['MyGame.UI.Panel']
local Nested = CSharp.AC['Outer+Nested'] -- 嵌套类型用 +
类型Lua 访问
无 namespaceCSharp.AC.Demo
含 namespaceCSharp.AC['MyGame.UI.Panel']
嵌套CSharp.AC['Outer+Nested']
BCLCSharp.mscorlib['System.Int32'] 等
注意

含点号的 namespace 不能 CSharp.AC.MyGame.UI.Panel 链式点开,必须字符串键。

  • 类型 懒加载;仅 public 可见
  • 静态与实例元数据 独立,不可混用

2. 静态成员(字段、属性、方法)​

-- 静态方法
print(CSharp.AC.Demo.Add(3, 5))

-- 静态字段 / 无参 Property
CSharp.AC.Demo.s_x = 10
print(CSharp.AC.Demo.GetSX())
C#Lua 读Lua 写
静态字段 s_xType.s_xType.s_x = v
静态无参 PropertyType.PropType.Prop = v
静态方法Type.Add(a, b)—

3. 构造实例​

local demo = CSharp.AC.Demo() -- ≡ new Demo()

有参构造支持默认重载分派;多构造见 方法重载。

4. 实例成员(字段、属性、方法)​

local demo = CSharp.AC.Demo()

demo:SetX(10) -- 实例方法(冒号传 self)
print(demo:GetX())

demo.x = 20 -- public 字段与无参 Property 写法相同
print(demo.x)
语法含义
demo:GetX()实例方法
demo.x字段或无参 Property
CSharp.AC.Demo.Add(3,5)静态方法

字段与 Property 要点​

  • 无参 { get; set; } 与字段语法一致;Il2Cpp Player 上简单 int property 可走 offset 快路径,热路径优先 demo.x 而非 GetX()
  • 带参 indexer(this[int])按 方法 分派,不能随意写 obj[i](szarray 等有专门规则,见 数组)
  • 未注册成员(字段 / 方法 / 属性)strict miss → error(zlua: member not found: …),不返回 nil,无反射 fallback

默认参数​

C# 方法 / 构造若带尾部默认参数,Lua 可省略对应实参,运行时补默认值:

public static int Foo(int x, int y = 5) => x + y;
print(CSharp.AC.Demo.Foo(1)) -- 6(y 用默认 5)
print(CSharp.AC.Demo.Foo(1, 9)) -- 10

多重载时优先选用「少用默认参数」的候选。细则见 方法重载。

继承​

子类实例可调基类 public 实例成员;静态成员走 声明类型 的类型表。

nil 与 null​

  • Lua nil → C# 引用类型 null;反之亦然
  • 值类型 struct 不能为 nil(除非 Nullable<T>,见 值类型)

5. Event(add_ / remove_)​

ZLua 没有 Event 专用元表(无 .get / .set / 赋值糖)。使用编译器生成的普通方法:

local function onChanged(v)
print("hp", v)
end

host:add_OnHealthChanged(onChanged)
-- ...
host:remove_OnHealthChanged(onChanged) -- 须同一 function 引用

静态 event:Type.add_Foo(handler)。handler 为 Lua function,按 Function 隐式 marshal。

若看到 OnX.get is nil,说明仍在用 xLua 式糖语法,改为 add_ / remove_。

完整示例(摘自 Demo)​

local function test_call_static_method()
print("Demo.Add:", CSharp.AC.Demo.Add(3, 5))
end

local function test_call_instance_method()
local demo = CSharp.AC.Demo()
print("Demo:GetX():", demo:GetX())
end

local function test_access_instance_field()
local demo = CSharp.AC.Demo()
demo:SetX(10)
assert(demo.x == 10)
demo.x = 20
assert(demo:GetX() == 20)
end

方法重载预告​

demo:Run(10) 与 demo:Run("hi") 在多重载时走运行时分派。精确点名用全签名键 demo['Run(System.Int32)'](demo, 10)(Bind 自动,无需 API);热路径短名用 [LuaAlias] 或 register_method。见 方法重载。

常见错误​

现象处理
type not found程序集名、namespace 括号、是否 public
zlua: member not found: …拼写 / 可见性;读未知成员现为 error(非 nil)
static member not found / 误访静态勿用实例访问静态;用类型表
member not writable只读 Property
Event .get 为 nil改用 add_ / remove_

学习路径​

上一篇EmmyLua 调试器
下一篇C# 调用 Lua

相关文档​