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

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


var methods = typeof(Foo).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod);
  foreach(var method in methods)
  {
   if(method.IsGenericMethod)
   {
    var paramters = method.GetParameters();
    if(paramters == null || paramters.Length == 0)
    {
     var genericMethod = method.MakeGenericMethod(new Type[] { typeof(int) });
     if(genericMethod != null)
     {
      genericMethod.Invoke(null, null);  // 输出 Int32              break;     }
    }
   }
  }

当然是反射啦, 这样就能让泛型方法退化为非泛型了, 虽然是一个缓慢的反射, 不过时间基本只花费在Invoke上, 问题还不大.

剩下的问题是重载了, 有非泛型和泛型的两个同名函数, 为了测试我先删除掉非泛型,


[SLua.CustomLuaClass]
public class Foo
{
 //public static void GetTypeName(System.Type type)
 //{
 // Debug.Log(type.Name);
 //}
 public static void GetTypeName<T>()
 {
  Debug.Log(typeof(T).Name);
 }
}

生成的lua注册代码也要修改一下


   System.Type a1;
   checkType(l,1,out a1);
   Foo.GetTypeName(a1);  // 它完了
   pushValue(l,true);

改成


System.Type a1;
   checkType(l,1,out a1);
   var methods = typeof(Foo).GetMethods(System.Reflection. BindingFlags.Public 
    | System.Reflection.BindingFlags.Static 
    | System.Reflection.BindingFlags.InvokeMethod);
   foreach(var method in methods)
   {
    if(method.IsGenericMethod)
    {
     var paramters = method.GetParameters();
     if(paramters == null || paramters.Length == 0)
     {
      var genericMethod = method.MakeGenericMethod(new Type[] { typeof(int) });
      if(genericMethod != null)
      {
       genericMethod.Invoke(null, null);
       break;
      }
     }
    }
   }
   pushValue(l,true);

试试运行一下看看, 输出 Int32 看来没有问题, 问题是在Lua那边还是需要手动封装了一遍:


rawset(Foo, "GetTypeName", function(type)
 local mt = getmetatable(Foo)
 local func = rawget(mt,"GetTypeName");
 func(type)
end)
-- 问题是, 不进行一次rawset无法得到泛型写法
Foo.GetTypeName(typeof(int));  // 输出 Int32 -- Table方法