亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#泛型方法在lua中表示的一種設計詳解

2019-10-29 19:32:15
字體:
來源:轉載
供稿:網友

前言

在進行lua方法注冊的時候, 大多數解決方案直接否定了泛型方法, 因為在lua側難以表達出泛型, 以及lua的函數重載問題,

函數重載問題可以通過一些特殊方法解決, 而泛型問題是主要問題, 以Unity + Slua的情況來說

比如下面的類:

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

一般只會生成  GetTypeName(System.Type type) 的注冊方法.

那么泛型的方法在Lua那邊該怎樣注冊才能讓這個調用能夠實現呢? 一般來說我們調用泛型方法必須在寫代碼的時候就確定, 像這樣:

Foo.GetTypeName<int>();  // 輸出 Int32

而lua并不能這樣約束, 它的調用必須還是非泛型的才可以, 這是第一個問題, 而第二個問題是lua那邊怎樣寫? 我們希望它的寫法能跟C#保持

一致, 或者相似吧, 讓人看起來容易明白, 可是lua中中括號是大于小于號, 不能這樣寫, 想想有沒有什么辦法

因為在lua中是沒有類型的, 類型必須來自C#, 所以只能將泛型作為非泛型方法才能使用, 如果讓函數進行一次退化和封裝, 像下面這樣

-- 先將C# 的typeof注冊成全局函數, 注冊System.Int32命名為intlocal Foo = {}Foo.GetTypeName = function(type) return function()   print(type.Name) endend
Foo.GetTypeName(typeof(int))();  -- luaFoo.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));  // 輸出 Int32rawset(Foo, "GetTypeName", function(type) return function()  local mt = getmetatable(Foo)  local func = rawget(mt,"GetTypeName");  func(type) endend)Foo.GetTypeName(typeof(int))();  // 輸出 Int32 -- 注意返回了function然后再次調用

 這個方法比較流氓, 因為直接默認了有非泛型函數, 并且覆蓋了元表的非泛型方法, 不可取的.

要繼續的話, 首先來看看一個泛型方法怎樣通過Type方法進行調用的:

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方法

 到這里, 基本就可以得出結論了,

一. 在lua中可以通過封裝(閉包)的方式接近C#的泛型的寫法, 差別只是一個中括號和小括號

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

然而過程異常復雜, 比如上述代碼中的rawset過程需要在C#的注冊代碼中進行實現, 而在調用的地方需要通過反射, 并且在lua側需要解決函數重載的問題,

上面的例子直接做了覆蓋. 就無法正常訪問非泛型方法函數了.

二. 既然泛型方法可以退化為非泛型, 那么可以直接檢測有沒有同名的且同參數的非泛型函數, 如果沒有就把泛型方法的非泛型版添加到注冊函數中即可.

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区二区三区久久| 国产欧美在线播放| 中文字幕精品影院| www.亚洲一二| 亚洲国产精品一区二区三区| 成人免费在线视频网址| 亚洲国产精品久久久久秋霞蜜臀| 色噜噜国产精品视频一区二区| 国产精品高潮呻吟视频| 日韩欧美高清在线视频| 日本a级片电影一区二区| 欧美日韩在线观看视频小说| 日韩福利在线播放| 亚洲а∨天堂久久精品9966| 国内精品模特av私拍在线观看| 国产不卡av在线免费观看| 亚洲第一页中文字幕| 国内精品视频在线| 国产精品自产拍在线观| 精品少妇v888av| 精品性高朝久久久久久久| 国产亚洲美女精品久久久| 国产中文欧美精品| 国产一区二区三区四区福利| 亚洲自拍欧美色图| 精品国产一区二区三区在线观看| 美女少妇精品视频| 亚洲石原莉奈一区二区在线观看| 精品毛片网大全| 日韩成人小视频| 亚洲一区二区久久久久久| 中文字幕日韩精品有码视频| 国产成人免费91av在线| 久久九九免费视频| 成人亚洲综合色就1024| 狠狠躁夜夜躁人人爽天天天天97| 亚洲美女av电影| 成人福利免费观看| 亚洲欧美成人网| 亚洲精品福利资源站| 琪琪第一精品导航| 久久影院中文字幕| 狠狠久久五月精品中文字幕| 91免费国产视频| 草民午夜欧美限制a级福利片| 91丝袜美腿美女视频网站| 久久亚洲一区二区三区四区五区高| 国产精品一二区| 日韩视频在线一区| 久久久国产精品视频| 欧美中在线观看| 亚洲成av人片在线观看香蕉| 国产精品直播网红| 热99精品只有里视频精品| 国产精品久久9| 欧美国产日韩xxxxx| 国产日韩欧美在线| 红桃av永久久久| 91久久久久久久| 国产亚洲欧美另类中文| 国产成人综合精品| 欧美精品18videosex性欧美| 欧美另类69精品久久久久9999| 国产精品日韩欧美大师| 国产亚洲欧洲高清一区| 国产在线视频一区| 欧美午夜无遮挡| 在线视频亚洲欧美| 日韩在线视频网站| 大桥未久av一区二区三区| 久久久久久久久久久免费| 亚洲国内精品视频| 亚洲三级 欧美三级| 亚洲视频第一页| 国产精品一香蕉国产线看观看| 日韩欧美在线观看视频| 91亚洲国产精品| 国产精品亚洲视频在线观看| 国内免费久久久久久久久久久| 国产区精品在线观看| 欧美午夜宅男影院在线观看| 日本在线观看天堂男亚洲| 欧美最顶级丰满的aⅴ艳星| 久久亚洲欧美日韩精品专区| 亚洲欧洲美洲在线综合| 国产色综合天天综合网| 伊人久久久久久久久久久久久| 国产成人在线播放| 日韩成人性视频| 精品高清一区二区三区| 精品国产成人在线| 97视频在线观看免费| 欧美精品一区二区三区国产精品| 国产男女猛烈无遮挡91| 91久久国产婷婷一区二区| 日韩av影片在线观看| 精品国产一区二区三区久久久| 国产精品久久久久国产a级| 26uuu久久噜噜噜噜| 欧美日韩国产黄| 欧美色播在线播放| 亚洲国产成人爱av在线播放| 国内成人精品视频| 欧美精品一本久久男人的天堂| 亚洲一二三在线| 91精品国产色综合久久不卡98口| 国产精品爽爽爽爽爽爽在线观看| 久久精品国产一区二区电影| www.精品av.com| 亚洲精品国产综合久久| 国产高清视频一区三区| 久久久久久久一区二区三区| 亚洲人成网站色ww在线| 一色桃子一区二区| 欧亚精品在线观看| 国产精品成人va在线观看| 国产精品入口福利| 亚洲成人中文字幕| 超碰97人人做人人爱少妇| 国产成人av在线播放| 狠狠色香婷婷久久亚洲精品| 久久久91精品国产一区不卡| 91网站在线免费观看| 日韩av免费在线观看| 伊人久久大香线蕉av一区二区| 亚洲免费福利视频| 欧美日韩国产成人在线观看| 欧美亚洲国产日本| 色综合色综合网色综合| 日本一区二区在线播放| 狠狠久久亚洲欧美专区| 国产精品美女视频网站| 亚洲成人精品久久| 久久国产精品99国产精| 久久久精品欧美| 奇米成人av国产一区二区三区| 国产精品一区二区三区在线播放| 亚洲自拍偷拍福利| 色yeye香蕉凹凸一区二区av| 亚洲va欧美va国产综合剧情| 日韩av不卡在线| 欧美激情高清视频| 久久99视频免费| 日韩极品精品视频免费观看| 91日韩在线视频| 午夜精品免费视频| 欧美视频裸体精品| 久久成人免费视频| 国产亚洲精品久久久久久| 欧美午夜精品伦理| 精品香蕉一区二区三区| 欧美裸体xxxx极品少妇| www国产亚洲精品久久网站| 国产精品久久久久久久久久东京| 成人福利网站在线观看| 精品亚洲一区二区三区在线播放| 亚洲欧美自拍一区| 日韩精品视频免费专区在线播放| 77777亚洲午夜久久多人| 亚洲精品少妇网址| 国产精品久久久久福利| 久久久999精品视频| 色青青草原桃花久久综合| 影音先锋欧美在线资源|