public T visit<T>(object arg, params object[] extrasArgs)
{
var methed=from m in GetType().GetMethods()
where m.Name == "Visit" && m.GetParameters().Length == 1 + extraArgs.Length
&& arg.GetType().IsAssignableFrom(m.GetParameters()[0].ParameterType)
&& m.ReturnType == typeof(T)
orderby m.GetParameters()[0].ParameterType.Name == arg.GetType().Name descending, m.GetParameters()[0].ParameterType.Name ascending
select m;
return (T)method.First().Invoke(this, new[] { arg }.Concat(extraArgs).ToArray());
}
今天看OXITE的Visitor,结果看的一头雾水,,麻烦哪位大侠给解释一下,,,
(1)public T visit<T>(object arg, params object[] extrasArgs)这种写法是什么意思
(2)麻烦对这个方法里面的代码解释一下
小弟拜谢
代码意思是说.
from m in GetType().GetMethods() 遍历一个类的方法.
where m.Name == "Visit" && m.GetParameters().Length == 1 + extraArgs.Length
条件是:这个方法名为Visit并且传进来的参数params object[] extrasArgs==这个方法要的参数个数-1(因为后面会再加进去一个参数arg)
arg.GetType().IsAssignableFrom(m.GetParameters()[0].ParameterType)
查看m的第一个参数是不是arg这个类Type实现的接口. 或者这个参数 是泛型类型参数且当前 Type 表示 ary的约束之一.
&& m.ReturnType == typeof(T)
这个m返回参数是不是这个函数的返回参数泛形T
orderby m.GetParameters()[0].ParameterType.Name == arg.GetType().Name descending, m.GetParameters()[0].ParameterType.Name ascending
等同sql里的升序和降序.第一个升序用的是重载方法的返回Bool类型的,说实话.我很少看到用这个方法的.一般都会用第二个降序里的返回一个实现了IComparer接口的方法.
return (T)method.First().Invoke(this, new[] { arg }.Concat(extraArgs).ToArray());
调用方法method(这个里面如果有多个满足上面条件的取第一个,没有就会出异常,因为method.Fisrt()要至少有一个方法才行.)并传参数进去(加入一个arg的参数).
总的来说,这个方法就是一个CALL,前面的都是查找是否有满足条件的方法.
如果T你不知道是什么意思.你有时间查吧.你先把他当做Object就好.T是泛形.在这个函数里只是用作先定义方法的返回值类型.
params上面说了,因为传进来的参数不知道有多少个就用这个来定义的.
多说几句.因为没有看过OXITE这个东东,他这个方法的设计我感到有点奇怪.因为从GetType()来说.他调用是应该就是本身的一个方法名为"Visit"的方法.不知为什么不直接调用.而转几圈来用.难道那个方法有多个重载还是什么的.有点想不通.
LZ可以自己下断点在这个方法上.然后查看他的具体执行过程.比别人说的来更实在.
上面的Linq to sql 语句大约等同如下Linq to object语句.
GetType().GetMethods().Where(
p => p.Name == "Visit" && p.GetParameters().Length == 1 + extrasArgs.Length
&& arg.GetType().IsAssignableFrom(p.GetParameters()[0].ParameterType)
&& p.ReturnType == typeof(T))
.OrderBy(
p => p.GetParameters()[0].ParameterType.Name == arg.GetType().Name)
.OrderByDescending
(p => p.GetParameters()[0].ParameterType.Name)
.Select(p => p);
(1)动态参数,参数数组;
(2)怎么看,都不像是C#代码。C#3.5?
T是泛型(自定义对象),后面的是动态数组。