2

你不写的理由是什么

list.Count.Equals(0) 

当你可能写

list.Count == 0

有技术/语义上的原因吗?

4

4 回答 4

5

我认为对于这种特定情况,两个陈述之间没有区别。由于您正在检查值的相等性int==运算符并Equals执行完全相同的操作。

但是对于其他一些情况,例如以下情况,它们可能返回不同的值;

Double.NaN == Double.NaN // is false
Double.NaN.Equals(Double.NaN) // is true

通常,对于值类型,您可以使用==; 但如果它是引用类型,最好使用Equals.

对于int样品的拆卸如下所示;生成的汇编代码不同,因此预期性能会有所不同;

            int a = 10;
00000080  mov         dword ptr [ebp-40h],0Ah 
                int b = 9;
00000087  mov         dword ptr [ebp-44h],9 

                bool x = a == b;
0000008e  mov         eax,dword ptr [ebp-40h] 
00000091  cmp         eax,dword ptr [ebp-44h] 
00000094  sete        al 
00000097  movzx       eax,al 
0000009a  mov         dword ptr [ebp-48h],eax 
                bool y = a.Equals(b);
0000009d  lea         ecx,[ebp-40h] 
000000a0  mov         edx,dword ptr [ebp-44h] 
000000a3  call        6B8803C0 
000000a8  mov         dword ptr [ebp-60h],eax 
000000ab  movzx       eax,byte ptr [ebp-60h] 
000000af  mov         dword ptr [ebp-4Ch],eax 
于 2013-02-15T08:08:28.007 回答
3

两个主要原因是

  1. list.Count == 0 更容易阅读(最重要)

  2. list.Count.Equals(0) 较慢

于 2013-02-15T08:01:19.943 回答
2

list.Count == 0具有更好的可读性和更短的 imo。如果性能可以忽略不计,请始终使用更具可读性并以最清晰的方式显示意图的内容。

至于技术原因:如果比较生成的两个 IL 序列。

  IL_0029:  callvirt   instance int32 class [mscorlib]System.Collections.Generic.List`1<string>::get_Count()
  IL_002e:  stloc.s    CS$0$0001
  IL_0030:  ldloca.s   CS$0$0001
  IL_0032:  ldc.i4.0
  IL_0033:  call       instance bool [mscorlib]System.Int32::Equals(int32) 
  // Equals(obj int) internally uses the method this == obj;

对比

  IL_007f:  callvirt   instance int32 class [mscorlib]System.Collections.Generic.List`1<string>::get_Count()
  IL_0084:  ldc.i4.0
  IL_0085:  ceq

有人可能会争辩说 == 运算符更快,因为它使用的指令更少,但没有人真正知道它是如何优化的。

使用 JIT 预热和首先调用的不同序列运行快速基准测试,您会注意到(至少在我的机器上)在超过 100000000 个元素的迭代中,== 快了大约 25 毫秒。

于 2013-02-15T08:30:02.333 回答
0

我认为更具可读性的是

if (list.IsEmpty()) { ... } 

我不是 C# 专家,所以你最好在这里查看推荐的方法来检查序列是否为空如何使其工作。

于 2013-02-15T08:12:36.330 回答