所以我现在正在学习MSIL来学习调试我的C#.NET应用程序.
我一直想知道:堆栈的目的是什么?
只是把我的问题放在上下文中:
为什么从内存转移到堆栈或"加载?" 另一方面,为什么会从堆栈转移到内存或"存储"?
为什么不将它们全部放在内存中?
我正在努力掌握这一点,以帮助我更深入地理解CIL代码.
用.NET语言编写的所有代码都编译为MSIL,但是只有使用MSIL才能直接执行特定的任务/操作吗?
让我们在MSIL中比C#,VB.NET,F#,j#或任何其他.NET语言更容易完成.
到目前为止我们有这个:
raise元素定义事件.main()方法作为.entrypoint.int和本机unsigned int类型.protected internal是fam 或 assem)<Module>类以定义全局函数或模块初始值设定项.我有机会发现C#编译器会改变这个方法:
static bool IsNotNull(object obj)
{
return obj != null;
}
Run Code Online (Sandbox Code Playgroud)
...进入这个CIL:
.method private hidebysig static bool IsNotNull(object obj) cil managed
{
ldarg.0 // obj
ldnull
cgt.un
ret
}
Run Code Online (Sandbox Code Playgroud)
...或者,如果您更喜欢查看反编译的C#代码:
static bool IsNotNull(object obj)
{
return obj > null; // (note: this is not a valid C# expression)
}
Run Code Online (Sandbox Code Playgroud)
怎么把它!=翻译成" >"?
作为MSIL和Java字节码之间的差异问题的一种跟进?,Java虚拟机的工作方式(主要)差异或相似之处是什么?.NET Framework 公共语言运行时(CLR)有效吗?
还有,是 .NET框架 CLR是"虚拟机"还是没有虚拟机的属性?
以下代码导致使用未分配的局部变量"numberOfGroups":
int numberOfGroups;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
numberOfGroups = 10;
}
Run Code Online (Sandbox Code Playgroud)
但是,这段代码工作正常(但ReSharper说这= 10是多余的):
int numberOfGroups = 10;
if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups))
{
numberOfGroups = 10;
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么,还是编译器不喜欢我||?
我把它缩小到dynamic导致问题(options在上面的代码中是一个动态变量).问题仍然存在,为什么我不能这样做?
此代码无法编译:
internal class Program
{
#region Static Methods
private static void Main(string[] args)
{
dynamic myString = args[0];
int myInt;
if(myString == null || !int.TryParse(myString, out myInt))
{
myInt …Run Code Online (Sandbox Code Playgroud) 昨天我发现了Christoph Nahr的一篇题为".NET Struct Performance"的文章,该文章 对几种语言(C++,C#,Java,JavaScript)进行了基准测试,为一种增加两个点结构(double元组)的方法.
事实证明,C++版本需要大约1000ms来执行(1e9次迭代),而C#在同一台机器上不能低于~3000ms(并且在x64中表现更差).
为了自己测试,我采用了C#代码(并略微简化为仅调用参数通过值传递的方法),并在i7-3610QM机器(3.1Ghz boost for single core),8GB RAM,Win8上运行. 1,使用.NET 4.5.2,RELEASE构建32位(x86 WoW64,因为我的操作系统是64位).这是简化版本:
public static class CSharpTest
{
private const int ITERATIONS = 1000000000;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Point AddByVal(Point a, Point b)
{
return new Point(a.X + b.Y, a.Y + b.X);
}
public static void Main()
{
Point a = new Point(1, 1), b = new Point(1, 1);
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < ITERATIONS; i++) …Run Code Online (Sandbox Code Playgroud) 以下操作的结果是什么解释?
k += c += k += c;
Run Code Online (Sandbox Code Playgroud)
我试图理解以下代码的输出结果:
int k = 10;
int c = 30;
k += c += k += c;
//k=80 instead of 110
//c=70
Run Code Online (Sandbox Code Playgroud)
目前我正在努力理解为什么"k"的结果是80.为什么分配k = 40不起作用(实际上Visual Studio告诉我该值没有在其他地方使用)?
为什么k 80而不是110?
如果我将操作拆分为:
k+=c;
c+=k;
k+=c;
Run Code Online (Sandbox Code Playgroud)
结果是k = 110.
我试图通过CIL查看,但是我在解释生成的CIL方面并没有那么深刻,也无法得到一些细节:
// [11 13 - 11 24]
IL_0001: ldc.i4.s 10
IL_0003: stloc.0 // k
// [12 13 - 12 24]
IL_0004: ldc.i4.s 30
IL_0006: stloc.1 // c
// [13 13 - 13 30]
IL_0007: ldloc.0 // …Run Code Online (Sandbox Code Playgroud) 使用ildasm和C#程序,例如
static void Main(string[] args)
{
}
Run Code Online (Sandbox Code Playgroud)
得到:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::Main
Run Code Online (Sandbox Code Playgroud)
hidebysig构造有什么作用?
在许多MSIL列表中,我观察到以下内容:
System.Nullable`1<!0> etc ...
Run Code Online (Sandbox Code Playgroud)
要么
class !0 etc ...
Run Code Online (Sandbox Code Playgroud)
!0在这些情况下,这意味着什么?
我想要做的是改变C#方法在调用时的执行方式,这样我就可以编写如下内容:
[Distributed]
public DTask<bool> Solve(int n, DEvent<bool> callback)
{
for (int m = 2; m < n - 1; m += 1)
if (m % n == 0)
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
在运行时,我需要能够分析具有Distributed属性(我已经可以做)的方法,然后在函数体执行之前和函数返回之后插入代码.更重要的是,我需要能够在不修改调用Solve的代码的情况下或在函数的开头修改代码(在编译时;在运行时这样做是目标).
目前我尝试了这段代码(假设t是Solve存储的类型,m是Solve的MethodInfo):
private void WrapMethod(Type t, MethodInfo m)
{
// Generate ILasm for delegate.
byte[] il = typeof(Dpm).GetMethod("ReplacedSolve").GetMethodBody().GetILAsByteArray();
// Pin the bytes in the garbage collection.
GCHandle h = GCHandle.Alloc((object)il, GCHandleType.Pinned);
IntPtr addr = h.AddrOfPinnedObject();
int size = il.Length;
// Swap the method.
MethodRental.SwapMethodBody(t, m.MetadataToken, …Run Code Online (Sandbox Code Playgroud)