08.XLua Lua访问C#中的方法

01.操作符重载和函数重载
C#中定义的操作符重载和函数重载在Lua中基本上能够使用,不过需要注意的是由于Lua中表示数值的类型只有一种(number),所以C#中对于数值类型之间的重载是不能够正确的识别的,通常只会调用类型符合的重载函数列表中先定义的函数

[LuaCallCSharp]
public class Overload
{
    public int Add(int num1, int num2)
    {
        Debug.Log("Add-int");
        return num1 + num2;
    }

    public float Add(float num1, float num2)
    {
        Debug.Log("Add-float");
        return num1 + num2;
    }

    public string Add(string num1, string num2)
    {
        Debug.Log("Add-string");
        return num1 + num2;
    }
}

local Overload=CS.Overload--获取一个类的映射
local overload=CS.Overload()--实例化一个类
print(overload:Add(1,2));
print(overload:Add(1.5,2.1));
print(overload:Add("22","22"));

08.XLua Lua访问C#中的方法_第1张图片
由于在Lua中只有一种数值类型(number),所以参数为int和float类型的Add函数都满足要求,这个时候会调用先定义的重载函数,也就是重载为int类型的Add
当先定义参数float类型后定义int类型的Add函数时,Lua代码调用就是参数类型为float的Add函数了

02.可变参数与默认参数
在Lua中调用它们的时候,参数的规则与C#中相同
对于C#的如下方法:
void VariableParamsFunc(int a, params string[] strs)
可以在lua里头这样调用:
testobj:VariableParamsFunc(5, ‘hello’, ‘john’)

  public void DefaultParam(int arg0, string arg1 = "1", int arg2 = 2)
    {
        Debug.Log("arg0:" + arg0);
        Debug.Log("arg1:" + arg1);
        Debug.Log("arg2:" + arg2);
    }

    public void VariableParam(int arg0, params string[] args)
    {
        Debug.Log("arg0:" + arg0);
        Debug.Log(args.Length);
        foreach (string arg in args)
        {
            Debug.Log(arg + " ");
        }
    }

local Overload=CS.Overload--获取一个类的映射
local overload=CS.Overload()--实例化一个类
overload:VariableParam(10,"1", "2", "3", "4");
overload:DefaultParam(1);

08.XLua Lua访问C#中的方法_第2张图片
03.访问C#枚举
枚举值就像枚举类型下的静态属性一样。
testobj:EnumTestFunc(CS.Tutorial.TestEnum.E1)
上面的EnumTestFunc函数参数是Tutorial.TestEnum类型的
另外,如果枚举类加入到生成代码的话,枚举类将支持__CastFrom方法,可以实现从一个整数或者字符串到枚举值的转换,例如:
CS.Tutorial.TestEnum.__CastFrom(1)
CS.Tutorial.TestEnum.__CastFrom(‘E1’)

在Lua中有以下五种方法可以访问到枚举变量:
1当作普通的静态属性访问
2使用__CastFrom函数,从枚举值对应的数值做类型转换
3使用__CastFrom函数,从枚举值对应的字符串做类型转换
4直接传入枚举值对应的数值
5直接传入枚举值对应的字符串


[LuaCallCSharp]
public enum Language
{
    C_PLUS_PLUS,
    C_SHARP
}


[LuaCallCSharp]
public class EnumParam
{
  public void PrintEnum(Language language)
  {
      switch(language){
           case Language.C_PLUS_PLUS:
                Debug.Log("C++");
                break;
            case Language.C_SHARP:
                Debug.Log("C#");
                break;
      }   
  }
}
--访问枚举
local enumParam=CS.EnumParam();
local Language=CS.Language;

--当作普通的静态属性访问
enumParam:PrintEnum(Language.C_PLUS_PLUS);
--直接传入枚举值对应的字符串
enumParam:PrintEnum("C_SHARP")
--直接传入枚举值对应的数值
enumParam:PrintEnum(1);
--使用__CastFrom函数,从枚举值对应的数值做类型转换
enumParam:PrintEnum(Language.__CastFrom("C_PLUS_PLUS"));
--使用__CastFrom函数,从枚举值对应的数值做类型转换
enumParam:PrintEnum(Language.__CastFrom(1));

08.XLua Lua访问C#中的方法_第3张图片
04.
访问C#委托
delegate使用(调用,+,-)
C#的delegate调用:和调用普通lua函数一样
+操作符:对应C#的+操作符,把两个调用串成一个调用链,右操作数可以是同类型的C# delegate或者是lua函数。
-操作符:和+相反,把一个delegate从调用链中移除。
Ps:delegate属性可以用一个luafunction来赋值。

[LuaCallCSharp]
class DelegateClass
{
    public delegate void ActionString(string arg);

    public ActionString action = (arg) =>
        {
            Debug.Log("action:" + arg);
        };

    public ActionString actionString1 = (arg) =>
        {
            Debug.Log("actionString1:" + arg);
        };

    public ActionString actionString2 = (arg) =>
        {
            Debug.Log("actionString2:" + arg);
        };
}

--访问委托
local delegateClass=CS.DelegateClass();
--使用delegateClass类的对象访问委托变量action
local action1=delegateClass.action;
action1("hi-1");
--由于在Lua中没有"+=""-="操作符,在增加委托链的时候只能使用"+""-"操作符
action1=action1+delegateClass.actionString1+delegateClass.actionString2;
action1("hi-2");
action1=action1-delegateClass.actionString2;
action1("hi-3");

08.XLua Lua访问C#中的方法_第4张图片
在使用Lua代码访问C#委托时需要注意,访问委托类型的方式与访问静态变量的方式相同,访问(静态/非静态)委托的变量的方式与访问(静态/非静态)成员变量的方式相同

--使用DelegateClass类访问委托类型ActionString,
--定义一个ActionString类型的委托变量action2
local DelegateClass=CS.DelegateClass;
local delegateClass=CS.DelegateClass();
---此时action2的值为nil
local action2=DelegateClass.ActionString;
action2=delegateClass.actionString1;
action2("hi-4");
action2=action2+delegateClass.actionString2;
action2("hi-5");

08.XLua Lua访问C#中的方法_第5张图片
05.访问C#事件
比如testobj里头有个事件定义是这样:public event Action TestEvent;
增加事件回调
testobj:TestEvent(’+’, lua_event_callback)
移除事件回调
testobj:TestEvent(’-’, lua_event_callback)

在访问C#事件的时候需要生成代码,所以必须要为事件的委托类型加上一个Attribute:[CSharpCallLua],关于为什么这里需要加[CSharpCallLua]而不是[LuaCallCSharp],在xLua的github主页的FAQ上作者是这么解释的:

LuaCallCSharp以及CSharpCallLua两种生成各在什么场景下用?
看调用者和被调用者,比如要在lua调用C#的GameObject.Find函数,或者调用gameobject的实例方法,属性等,GameObject类要加LuaCallSharp,而想把一个lua函数挂到UI回调,这是调用者是C#,被调用的是一个lua函数,所以回调声明的delegate要加CSharpCallLua。
有时会比较迷惑人,比如List.Find(Predicate match)的调用,List当然是加LuaCallSharp,而Predicate却要加CSharpCallLua,因为match的调用者在C#,被调用的是一个lua函数。
更无脑一点的方式是看到“This delegate/interface must add to CSharpCallLua : XXX”,就把XXX加到CSharpCallLua即可。

[LuaCallCSharp]
class EventClass
{
    //在访问C#事件的时候需要生成代码
    //所以必须要为事件的委托类型加上一个Attribute:[CSharpCallLua],
    [CSharpCallLua]
   public delegate void EventAction();
   public event EventAction Events;
   public EventAction action1 = () =>
   {
           Debug.Log("action1");
   };

    public EventAction action2 = () =>
    {
            Debug.Log("action2");
    };

    public void TriggerEvent()
    {
        Events();
    }
}

在添加事件的时候,既可以使用C#中的委托变量,也可以使用Lua中的函数

同时在添加和移除事件的时候应该使用以下的方式

object:event("+", delegate)
object:event("-", delegate)

function lua_action()
    print("lua_action:")
end

local eventClass=CS.EventClass();
eventClass:Events("+",lua_action);
eventClass:Events("+",eventClass.action1);
eventClass:Events("+",eventClass.action2);
eventClass:TriggerEvent();

08.XLua Lua访问C#中的方法_第6张图片

你可能感兴趣的:(Lua)