簡體   English   中英

C#反射if:0等於1?

[英]C# reflection if: 0 equals 1?

我有問題。 這是我的代碼:

var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
var g = method.GetILGenerator();
g.DeclareLocal(typeof(int));

Label inequality = g.DefineLabel();
Label equality = g.DefineLabel();
Label end = g.DefineLabel();

g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Call, typeof(String).GetMethod("op_Equality", new Type[]{typeof(string), typeof(string)}));
g.Emit(OpCodes.Stloc_0);
g.Emit(OpCodes.Ldloc_0);
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(int)}));
g.Emit(OpCodes.Ldloc_0);
g.Emit(OpCodes.Ldc_I4_1);
g.Emit(OpCodes.Ceq);
g.Emit(OpCodes.Brtrue_S, equality);
g.Emit(OpCodes.Brfalse_S, inequality);
g.MarkLabel(inequality);
g.Emit(OpCodes.Ldstr, "Specified strings are different.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)}));
g.Emit(OpCodes.Br_S, end);
g.MarkLabel(equality);
g.Emit(OpCodes.Ldstr, "Specified strings are same.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
g.Emit(OpCodes.Br_S, end);
g.MarkLabel(end);
g.Emit(OpCodes.Ret);

var action = (Action)method.CreateDelegate(typeof(Action));
action();

這是我的結果:

1
Specified strings are different.

但為什么輸出錯了? Ceq指令比較op_Equation的結果為1,堆棧的頂部為0。 1 不等於 0.那么為什么呢? 錯誤在哪里? 請幫我。

g.Emit(OpCodes.Brtrue_S, inequality);之后g.Emit(OpCodes.Brtrue_S, inequality); ,您需要手動跳轉到“相等”語句。 否則它無論如何都會執行下一條指令。 所以你需要在它之后插入以下行:

g.Emit(OpCodes.Br_S, equality);

此外,無論如何,當它被聲明為下一條指令時跳轉到標簽equality是沒有意義的。 所以刪除它。

所以該部分將如下所示:

g.Emit(OpCodes.Ceq);

g.Emit(OpCodes.Brtrue_S, inequality); // if true goto inequality
g.Emit(OpCodes.Br_S, equality); // else goto equality

g.MarkLabel(inequality);            
g.Emit(OpCodes.Ldstr, "Specified strings are different.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)}));
g.Emit(OpCodes.Br_S, end); // goto end

g.MarkLabel(equality);
g.Emit(OpCodes.Ldstr, "Specified strings are same.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));

g.MarkLabel(end);
g.Emit(OpCodes.Ret);

你的分支是標簽“不平等”,它仍然緊跟在聲明之后。 因此,無論您是否分支,這都是將被調用的代碼。 你應該分支到“平等”這個標簽。

另外,你的行g.Emit(OpCodes.Brfalse_S, equality); 沒有意義,因為它永遠不會到達 - 你在前面的陳述中跳過它。 並且一旦邏輯被修復,你的“不等式”標簽實際上不會被用到任何地方,所以你也可以放棄它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM