背景:我正在研究特定于域的 CLI 实现。这个实现有望使用 Mono 或其部分包含的 BCL。它不使用 Mono 的任何其他部分——它从头开始实现 CLR/VES 本身。现在我正在研究 CLR 本身和 BCL 之间的“边界层”,因此我可以确保我的 CLR 将按照 BCL 的预期方式运行。
我在 Mono BCL 源代码中遇到了一些我难以理解的东西。它在执行中System.Delegate
:
...
private object m_target;
...
public MethodInfo Method {
...
}
...
#if NET_2_0
public object DynamicInvoke (params object[] args)
#else
public object DynamicInvoke (object[] args)
#endif
{
return DynamicInvokeImpl (args);
}
protected virtual object DynamicInvokeImpl (object[] args)
{
if (Method == null) {
Type[] mtypes = new Type [args.Length];
for (int i = 0; i < args.Length; ++i) {
mtypes [i] = args [i].GetType ();
}
method_info = m_target.GetType ().GetMethod (data.method_name, mtypes);
}
#if NET_2_0
if ((m_target != null) && Method.IsStatic) {
// The delegate is bound to m_target
if (args != null) {
object[] newArgs = new object [args.Length + 1];
args.CopyTo (newArgs, 1);
newArgs [0] = m_target;
args = newArgs;
} else {
args = new object [] { m_target };
}
return Method.Invoke (null, args);
}
#endif
return Method.Invoke (m_target, args);
}
我在看DynamicInvokeImpl
。第一点很清楚:它是MethodInfo
根据被调用的签名来获取的。
事情在第二次之后变得奇怪#if NET_2_0
。看起来如果提供了一个目标对象,并且被调用的方法是 static,它会向参数添加一个“this”指针!
它继续将这个可能修改过的参数列表传递给MethodInfo.Invoke
. 我查看了该方法的 MSDN 文档,似乎很清楚即使调用实例方法,也不应该包含“this”指针 - 更不用说为静态方法添加一个了!
请记住,这不是调用 Mono 的某些内部部分,它可以以任何他们想要的方式工作 - 它调用了一个定义良好的公共方法System.Reflection.MethodInfo
!
我知道 CLR 必须将隐藏参数(通常是类型句柄)插入到泛型类的静态方法调用中。但是,1)这是一个“this”引用,而不是类型句柄,2)代码似乎是在批发,而不仅仅是针对泛型类,以及 3)类似的事情将在较低级别完成,而不是由的来电者MethodInfo.Invoke
!
任何线索这里发生了什么?