提交 55353166 编写于 作者: J johnche(车雄生)

this[string field]或者this[object field]操作符重载新增get_Item和set_Item调用,用于无法添加C#方法时的lua调用。

上级 4b024fbf
......@@ -158,9 +158,18 @@ end)
## this[string field]或者this[object field]操作符重载为什么在lua无法访问?(比如Dictionary\<string, xxx\>, Dictionary\<object, xxx\>在lua中无法通过dic['abc']或者dic.abc检索值)
在2.1.5~2.1.6版本把这个特性去掉,因为:1、这个特性会导致基类定义的方法、属性、字段等无法访问(比如Animation无法访问到GetComponent方法);2、key为当前类某方法、属性、字段的名字的数据无法检索,比如Dictionary类型,dic['TryGetValue']返回的是一个函数,指向Dictionary的TryGetValue方法。
因为:1、这个特性会导致基类定义的方法、属性、字段等无法访问(比如Animation无法访问到GetComponent方法);2、key为当前类某方法、属性、字段的名字的数据无法检索,比如Dictionary类型,dic['TryGetValue']返回的是一个函数,指向Dictionary的TryGetValue方法。
建议直接方法该操作符的等效方法,比如Dictionary的TryGetValue,如果该方法没有提供,可以在C#那通过Extension method封装一个使用。
如果你的版本大于2.1.11,可以用get_Item来获取值,用set_Item来设置值。要主要只有this[string field]或者this[object field]才有这两个替代api,其它类型的key是没有的。
~~~lua
dic:set_Item('a', 1)
dic:set_Item('b', 2)
print(dic:get_Item('a'))
print(dic:get_Item('b'))
~~~
如果你的版本小于或等于2.1.11,建议直接方法该操作符的等效方法,比如Dictionary的TryGetValue,如果该方法没有提供,可以在C#那通过Extension method封装一个使用。
## 有的Unity对象,在C#为null,在lua为啥不为nil呢?比如一个已经Destroy的GameObject
......
......@@ -1152,7 +1152,12 @@ namespace XLua
var instanceMethods = toBeWrap.GetMethods(instanceFlag)
.Concat(extensionMethods == null ? Enumerable.Empty<MethodInfo>() : Utils.GetExtensionMethodsOf(toBeWrap))
.Where(m => Utils.IsSupportedMethod(m))
.Where(m => !m.IsSpecialName).GroupBy(m => m.Name).ToList();
.Where(m => !m.IsSpecialName
|| (
((m.Name == "get_Item" && m.GetParameters().Length == 1) || (m.Name == "set_Item" && m.GetParameters().Length == 2))
&& m.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(string))
)
).GroupBy(m => m.Name).ToList();
var supportOperators = toBeWrap.GetMethods(staticFlag)
.Where(m => m.IsSpecialName && InternalGlobals.supportOp.ContainsKey(m.Name))
.GroupBy(m => m.Name);
......
......@@ -307,7 +307,12 @@ namespace CSObjectWrapEditor
//warnning: filter all method start with "op_" "add_" "remove_" may filter some ordinary method
parameters.Set("methods", type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.IgnoreCase | BindingFlags.DeclaredOnly)
.Where(method => !method.IsDefined(typeof (ExtensionAttribute), false) || method.GetParameters()[0].ParameterType.IsInterface || method.DeclaringType != type)
.Where(method => !method.IsSpecialName)
.Where(method => !method.IsSpecialName
|| (
((method.Name == "get_Item" && method.GetParameters().Length == 1) || (method.Name == "set_Item" && method.GetParameters().Length == 2))
&& method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(string))
)
)
.Concat(extension_methods)
.Where(method => !IsDoNotGen(type, method.Name))
.Where(method => !isMethodInBlackList(method) && (!method.IsGenericMethod || extension_methods.Contains(method) || isSupportedGenericMethod(method)) && !isObsolete(method))
......
......@@ -405,7 +405,16 @@ namespace XLua.CSObjectWrap
end
end)%>) <%end%>
{
<%
<%if overload.Name == "get_Item" and overload.IsSpecialName then
local keyType = overload:GetParameters()[0].ParameterType%>
<%=GetCasterStatement(keyType, 2, "key", true)%>;
<%=GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")%>;
<%elseif overload.Name == "set_Item" and overload.IsSpecialName then
local keyType = overload:GetParameters()[0].ParameterType
local valueType = overload:GetParameters()[1].ParameterType%>
<%=GetCasterStatement(keyType, 2, "key", true)%>;
<%=GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")%>;
<% else
in_pos = 0;
ForEachCsList(parameters, function(parameter, pi)
if pi >= real_param_count then return end
......@@ -444,6 +453,7 @@ namespace XLua.CSObjectWrap
<%
end
end)
end
%>
<%if NeedUpdate(type) and not method.IsStatic then%>
<%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;
......
......@@ -449,7 +449,6 @@ namespace XLua
LuaAPI.lua_rawset(L, is_static ? cls_field : obj_field);
}
Dictionary<string, PropertyInfo> prop_map = new Dictionary<string, PropertyInfo>();
List<PropertyInfo> items = new List<PropertyInfo>();
PropertyInfo[] props = type.GetProperties(flag);
for (int i = 0; i < props.Length; ++i)
......@@ -459,10 +458,6 @@ namespace XLua
{
items.Add(prop);
}
else
{
prop_map.Add(prop.Name, prop);
}
}
var item_array = items.ToArray();
......@@ -483,14 +478,21 @@ namespace XLua
continue;
}
PropertyInfo prop = null;
if (method_name.StartsWith("add_") || method_name.StartsWith("remove_")
|| method_name == "get_Item" || method_name == "set_Item")
//indexer
if (method.IsSpecialName && ((method.Name == "get_Item" && method.GetParameters().Length == 1) || (method.Name == "set_Item" && method.GetParameters().Length == 2)))
{
if (!method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(string)))
{
continue;
}
}
if ((method_name.StartsWith("add_") || method_name.StartsWith("remove_")) && method.IsSpecialName)
{
continue;
}
if (method_name.StartsWith("op_")) // 操作符
if (method_name.StartsWith("op_") && method.IsSpecialName) // 操作符
{
if (InternalGlobals.supportOp.ContainsKey(method_name))
{
......@@ -503,26 +505,18 @@ namespace XLua
}
continue;
}
else if (method_name.StartsWith("get_") && method.IsSpecialName) // getter of property
else if (method_name.StartsWith("get_") && method.IsSpecialName && method.GetParameters().Length != 1) // getter of property
{
string prop_name = method.Name.Substring(4);
if (!prop_map.TryGetValue(prop_name, out prop))
{
prop = type.GetProperty(prop_name);
}
LuaAPI.xlua_pushasciistring(L, prop.Name);
translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop.Name, new MethodBase[] { method }).Call);
LuaAPI.xlua_pushasciistring(L, prop_name);
translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
LuaAPI.lua_rawset(L, method.IsStatic ? cls_getter : obj_getter);
}
else if (method_name.StartsWith("set_") && method.IsSpecialName) // setter of property
else if (method_name.StartsWith("set_") && method.IsSpecialName && method.GetParameters().Length != 2) // setter of property
{
string prop_name = method.Name.Substring(4);
if (!prop_map.TryGetValue(prop_name, out prop))
{
prop = type.GetProperty(prop_name);
}
LuaAPI.xlua_pushasciistring(L, prop.Name);
translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop.Name, new MethodBase[] { method }).Call);
LuaAPI.xlua_pushasciistring(L, prop_name);
translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
LuaAPI.lua_rawset(L, method.IsStatic ? cls_setter : obj_setter);
}
else if (method_name == ".ctor" && method.IsConstructor)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册