在什么情况下我在C#中运行?

时间:2012-07-07 12:15:33

标签: c# .net .net-4.0

我在想......

当我有这样的代码时:

lock (obj)
{
    MyCode.MyAgent();
}

MyAgent可以包含识别的代码它在lock块下运行吗?

怎么样:

for (int i=0;i<5;i++)
{
   MyCode.MyAgent();
}

MyAgent可以包含识别的代码它在loop块下运行吗?

可以询问using块,unsafe代码等同样的问题...... - 你明白了......

这在C#中是否可行?

这只是一个理论问题,我不想做任何事情......只是知识。

3 个答案:

答案 0 :(得分:8)

这并非完全不可能,您可以使用StackTrace类来获取对调用方法的引用,并使用MethodInfo.GetMethodBody()来获取该方法的IL。

但是你永远不会得到这种可靠性,即时编译器的优化器会让你很难确定呼叫的确切位置。方法体内联将使方法完全消失。循环展开将使得无法了解循环索引。优化器使用cpu寄存器来存储局部变量和方法参数,从而无法获得可靠的变量值。

更不用说反编译IL的锡箔咀嚼效果了。这些都不是只是将参数传递给方法的简单性和速度。

答案 1 :(得分:3)

否(禁止代码明确地将此信息转发给方法)。

这样做的原因是这些概念不会转换为在IL或元数据中保留的结构化信息,然后CLR可以在运行时向您公开。将其与在元数据中编码的类进行对比,从而在运行时启用反射。

尝试保留这些信息会导致复杂性增加,当然还有额外的开销,因为如果你需要你的程序保持这种状态,那么很容易在代码中实现这一点(是否需要这个状态是个好主意)另一个问题)。

答案 2 :(得分:0)

我不相信.NET支持您直接描述的功能,尽管您可以通过使用StackFrame获取当前调用堆栈并使用反射来分析方法体等来获取该信息。我不确定你有多精确。

.NET确实有同步的上下文,但不是你要求的级别。例如,请查看System.ContextBoundObject