为什么我不应该写清单.计数.等于(0)

本文关键字:等于 计数 不应该 为什么 | 更新日期: 2023-09-27 17:59:32

你不写的理由是什么

list.Count.Equals(0) 

当你可能写的时候

list.Count == 0

是否有技术/语义原因?

为什么我不应该写清单.计数.等于(0)

我认为对于这种特定情况,两个陈述之间没有区别。由于您正在检查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 

两个主要原因是

  1. 列表。计数 == 0 更容易阅读(最重要的(

  2. 列表。Count.Equals(0( 较慢

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 毫秒。

我认为更具可读性是

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

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