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"));

由于在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);
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));
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");
在使用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");
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中的函數
同時在添加和移除事件的時候應該使用以下的方式
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();