C#泛型方法在lua中表示的一种设计详解

2020-01-05 10:08:47丽君


-- 先将C# 的typeof注册成全局函数, 注册System.Int32命名为int
local Foo = {}
Foo.GetTypeName = function(type)
 return function() 
  print(type.Name)
 end
end

Foo.GetTypeName(typeof(int))();  -- lua
Foo.GetTypeName<typeof(int)>();  // C#

这样写的话, 除了尖括号, 基本就能两边一致了对吧, 运行结果也是一样的


/*至于怎样注册typeof(int)*/
// 在LuaState的Init中注册个全局函数[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
internal static int getType(IntPtr L)
{
  System.Type type = null;
  LuaObject.checkType(L, 1, out type);
  LuaObject.pushObject(L, type);
  return 1;
}
// 在LuaState的Init中自己注册咯LuaDLL.lua_pushcfunction(L, getType);LuaDLL.lua_setglobal(L, "typeof");

// CustomExport.OnAddCustomClass 中添加类型别名
add(typeof(System.Int32), "int"); // int

 只是这里lua的函数没有进行C#那边的调用啊, 下一步就来看看有没有什么办法来实现调用.

如果通过自动注册的话, Foo应该是一个已经注册的类型.


[SLua.CustomLuaClass]
public class Foo

并且有元表, 元表里面有非泛型的GetTypeName方法了. 现在先不要去动元表,

直接注册这个到Table里面, 因为如果Table里面有值的话, 就不会去查询元表了


import "Foo";
Foo.GetTypeName(typeof(int));  // 输出 Int32

rawset(Foo, "GetTypeName", function(type)
 return function()
  local mt = getmetatable(Foo)
  local func = rawget(mt,"GetTypeName");
  func(type)
 end
end)

Foo.GetTypeName(typeof(int))();  // 输出 Int32 -- 注意返回了function然后再次调用

 这个方法比较流氓, 因为直接默认了有非泛型函数, 并且覆盖了元表的非泛型方法, 不可取的.

要继续的话, 首先来看看一个泛型方法怎样通过Type方法进行调用的: