[C# 4.0] 1. Dynamic
2010-09-30 21:04:24 来源:WEB开发网事情落到了 "MakeUpdateDelegate()" 头上。CallSite<T> 内部提供了一个 _CachedUpdate 字段用来缓存以提高性能。
public sealed class CallSite<T> : CallSite where T: class
{
internal T MakeUpdateDelegate()
{
Type[] typeArray;
Type delegateType = typeof(T);
MethodInfo method = delegateType.GetMethod("Invoke");
if (delegateType.IsGenericType && CallSite<T>.IsSimpleSignature(method, out typeArray))
{
MethodInfo info2 = null;
MethodInfo info3 = null;
if (method.ReturnType == typeof(void))
{
if (delegateType == DelegateHelpers.GetActionType(typeArray.AddFirst<Type>(typeof(CallSite))))
{
info2 = typeof(UpdateDelegates).GetMethod("UpdateAndExecuteVoid" + typeArray.Length,
BindingFlags.NonPublic | BindingFlags.Static);
info3 = typeof(UpdateDelegates).GetMethod("NoMatchVoid" + typeArray.Length,
BindingFlags.NonPublic | BindingFlags.Static);
}
}
else if (delegateType == DelegateHelpers.GetFuncType(typeArray.AddFirst<Type>(typeof(CallSite))))
{
info2 = typeof(UpdateDelegates).GetMethod("UpdateAndExecute" + (typeArray.Length - 1),
BindingFlags.NonPublic | BindingFlags.Static);
info3 = typeof(UpdateDelegates).GetMethod("NoMatch" + (typeArray.Length - 1),
BindingFlags.NonPublic | BindingFlags.Static);
}
if (info2 != null)
{
CallSite<T>._CachedNoMatch = (T) info3.MakeGenericMethod(typeArray).CreateDelegate(delegateType);
return (T) info2.MakeGenericMethod(typeArray).CreateDelegate(delegateType);
}
}
CallSite<T>._CachedNoMatch = this.CreateCustomNoMatchDelegate(method);
return this.CreateCustomUpdateDelegate(method);
}
}
private T CreateCustomNoMatchDelegate(MethodInfo invoke)
{
ParameterExpression[] parameters = invoke.GetParametersCached()
.Map<ParameterInfo, ParameterExpression>(p => Expression.Parameter(p.ParameterType, p.Name));
ParameterExpression expression1 = parameters[0];
return Expression.Lambda<T>
(
Expression.Block
(
Expression.Call(typeof(CallSiteOps).GetMethod("SetNotMatched"), parameters
.First<ParameterExpression>()),
Expression.Default(invoke.GetReturnType())
),
parameters
).Compile();
}
private T CreateCustomUpdateDelegate(MethodInfo invoke)
{
Expression expression9;
List<Expression> list = new List<Expression>();
List<ParameterExpression> list2 = new List<ParameterExpression>();
... ...
return Expression.Lambda<T>
(
Expression.Label
(
target,
Expression.Block
(
(IEnumerable<ParameterExpression>) new ReadOnlyCollection<ParameterExpression>(list2),
(IEnumerable<Expression>) new ReadOnlyCollection<Expression>(list)
)
),
"CallSite.Target",
true,
new ReadOnlyCollection<ParameterExpression>(array)
).Compile();
}
更多精彩
赞助商链接