跳到主要内容

Lua 访问 C# 基础

Lua 侧通过全局 CSharp 根表访问所有 C# 类型,语义贴近 C#:Type() 构造、obj:Method() 调用实例方法、静态成员走类型表。

Canonical 示例:zlua-demo/LuaScripts/app.luaAssets/Demo.cs

概述

  • 类型与程序集 懒加载:首次访问时注册元表
  • public 成员可见
  • 静态成员与实例成员使用 独立 元数据,不可混用

CSharp 表结构

CSharp -- 根表
└─ Assembly-CSharp -- 程序集(默认游戏脚本)
└─ Demo -- 无 namespace 的全局类型
└─ ['MyGame.UI.Panel'] -- 含 namespace 必须括号

程序集别名(推荐)

程序集名较长时设短别名:

CSharp['AC'] = CSharp['Assembly-CSharp']

local demo = CSharp.AC.Demo()

Demo 在 app.lua 第 1 行 使用此惯例。

类型解析规则

类型Lua 访问
无 namespace 全局类CSharp.AC.Demo
含 namespaceCSharp.AC['MyGame.UI.Panel']
嵌套类型CSharp.AC['Outer+Nested']+ 分隔,须括号)
mscorlib / SystemCSharp.mscorlib['System.Int32']
注意

点号的 namespace 不能用 CSharp.AC.MyGame.UI.Panel 链式访问,必须用字符串键:CSharp.AC['MyGame.UI.Panel']

构造实例

无参构造直接 调用类型表

local demo = CSharp.AC.Demo()

等价于 C# 的 new Demo()。有参构造在 Mono 上支持重载 dispatch;多构造函数见 方法重载

静态成员

-- 静态方法
local sum = CSharp.AC.Demo.Add(3, 5)

-- 静态字段
CSharp.AC.Demo.s_x = 10
local x = CSharp.AC.Demo.GetSX()

实例成员

local demo = CSharp.AC.Demo()

-- 实例方法(冒号语法传递 self)
demo:SetX(10)
local v = demo:GetX()

-- 字段(与无参 Property 写法相同)
demo.x = 20
print(demo.x)

点号 vs 冒号

语法含义
demo:GetX()实例方法,等价 C# demo.GetX()
CSharp.AC.Demo.Add(3,5)静态方法
demo.x字段或无参 property

继承

子类实例可调用基类 public 实例成员;静态成员走 声明类型 的类型表。继承链上的重载与 new 隐藏规则见 类型系统规范 §5。

nil 与 null

  • Lua nil 传给 C# 引用类型形参 → null
  • C# 返回 null 引用 → Lua nil
  • 值类型 struct 不能为 nil(除非 Nullable<T>

完整示例(摘自 Demo)

local function test_call_static_method()
print("Demo.Add:", CSharp.AC.Demo.Add(3, 5))
print("Demo.Multi:", CSharp.AC.Demo.Multi(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

Mono / Il2Cpp 支持

能力MonoIl2Cpp
CSharp 懒加载
无 namespace 类型
namespace 括号访问⚠️ 随类型扩展
静态 / 实例字段
静态 / 实例方法⚠️ 手写桥接
继承⚠️

常见错误

错误信息 / 现象处理
type not found检查程序集名、namespace 括号、类型是否 public
static member not found勿通过实例访问静态成员;用类型表
instance member not found键名拼写;该成员是否 public
嵌套类型失败使用 Outer+Nested 全名

学习路径

上一篇C# 调用 Lua
下一篇字段与属性

相关文档