跳到主要内容

Lua 调用 C#

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

Canonical:app.luaDemo.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 misserror,无反射 fallback

继承

子类实例可调基类 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
static member not found勿用实例访问静态;用类型表
instance member not found拼写 / 可见性
member not writable只读 Property
Event .get 为 nil改用 add_ / remove_

学习路径

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

相关文档