如果我有一个返回值的方法(例如Remove
类的Dictionary
方法返回bool
),如果我没有将返回值赋给a {变量?换句话说,如果我在没有将结果分配给dictionary.Remove("plugin-01");
变量的情况下编写bool
,那么编译与bool b = dictionary.Remove("plugin-01");
的区别是什么?
答案 0 :(得分:15)
让我们看一个简单的例子和它产生的IL代码(由LinqPad提供)
void Main()
{
Bar();
Baz();
}
bool Bar()
{
return true;
}
void Baz()
{
Console.WriteLine("placeholder");
}
这产生以下IL:
IL_0000: ldarg.0
IL_0001: call UserQuery.Bar
IL_0006: pop //remove current value from evaluation stack
IL_0007: ldarg.0
IL_0008: call UserQuery.Baz
Bar:
IL_0000: ldc.i4.1
IL_0001: ret
Baz:
IL_0000: ldstr "placeholder"
IL_0005: call System.Console.WriteLine
IL_000A: ret
你可以看到Bar
被调用,然后一个pop来从评估堆栈中删除布尔返回值 - 它无处可去。我必须更新示例以包含对Baz()
的另一个方法调用,否则不会发出pop,因为程序结束。
现在让我们看一下我们实际使用返回值的情况:
void Main()
{
bool foo = Bar();
Console.WriteLine(foo);
}
bool Bar()
{
return true;
}
这产生以下IL:
IL_0000: ldarg.0
IL_0001: call UserQuery.Bar
IL_0006: stloc.0 //pops current value from evaluation stack, stores in local var
IL_0007: ldloc.0
IL_0008: call System.Console.WriteLine
Bar:
IL_0000: ldc.i4.1
IL_0001: ret
忽略System.Console.WriteLine
部分,包括IL_007
之后的所有部分 - 只需添加它,这样编译器就不会优化变量的使用。您会看到Bar
方法调用的结果从评估堆栈中弹出并存储在局部变量foo
中。这就是区别 - 要么抓取并删除返回值的pop
,要么将stloc.0
分配给变量。
因此,如果您不需要方法调用的结果,则应该忽略结果。即使您将结果分配给变量并且该变量从未使用过,编译器也可能完全优化掉变量和赋值 - 至少在发布模式下(在调试模式下,大多数优化都被禁用以改善您的调试体验)。 p>
答案 1 :(得分:3)
如果你不使用它,那么简单地会忽略返回值。
您可以执行类似
的操作if(!dictionary.Remove("plugin-01")) {
MessageBox.Show("Error: plugin-01 does not exist!");
}
如果你不在乎,你可以安全地写
dictionary.Remove("plugin-01");
答案 2 :(得分:1)
调用部分相同,但在IL中跳过赋值部分。看一看 - 这是一个简单程序的反汇编:
var d = new Dictionary<int,int>();
bool a = d.Remove(5);
d.Remove(6);
反汇编看起来像这样:
bool a = d.Remove(5);
00000057 mov ecx,dword ptr [ebp-40h]
0000005a mov edx,5
0000005f cmp dword ptr [ecx],ecx
00000061 call 69106A00
// Here is the assignment part
00000066 mov dword ptr [ebp-4Ch],eax
00000069 movzx eax,byte ptr [ebp-4Ch]
0000006d mov dword ptr [ebp-44h],eax
d.Remove(6);
00000070 mov ecx,dword ptr [ebp-40h]
00000073 mov edx,6
00000078 cmp dword ptr [ecx],ecx
0000007a call 69106A00
前四行是常见的;第一次通话的最后三行处理作业;在第二次通话的反汇编中它们丢失了。