Rud*_*dey 0 .net vb.net comparison equals value-type
请参阅以下代码:
Private Function EqualsNothing(ByVal item As Object) As Boolean
Return item.Equals(Nothing)
End Function
Console.WriteLine(0.Equals(Nothing)) ' True
Console.WriteLine(EqualsNothing(0)) ' False
Run Code Online (Sandbox Code Playgroud)
如何Equals在拳击结构后避免返回不同的东西?有没有办法调用原始Equals实现?
我知道=在这种情况下我可以使用运算符,但是EqualsNothing应该同时使用类和结构.该=运营商将不会VB.NET带班工作,也不会与没有执行这个操作结构的工作.Equals 确实适用于所有事情,但正如我在上面演示的那样,Equals拳击后不会返回相同的东西.
那么,我应该如何重写EqualsNothing以使其适用于类和结构?
编辑:我尝试制作EqualsNothing通用,但这没有帮助.
我通常是一个C#人,所以我用Linqpad用这段代码演示了这种行为:
dim a as object
dim b as object
dim i as object
a = 0.Equals(Nothing)
Console.WriteLine("a={0}", a.ToString())
i = 0
b = i.Equals(Nothing)
Console.WriteLine("b={0}", b.ToString())
Run Code Online (Sandbox Code Playgroud)
将0放在对象中i强制该框,就像调用方法一样.
结果如问题所示:
a=True
b=False
Run Code Online (Sandbox Code Playgroud)
产生的IL是:
IL_0001: ldc.i4.0
IL_0002: stloc.3
IL_0003: ldloca.s 03
IL_0005: ldc.i4.0
IL_0006: call System.Int32.Equals
IL_000B: box System.Boolean
IL_0010: stloc.0
IL_0011: ldstr "a={0}"
IL_0016: ldloc.0
IL_0017: callvirt System.Object.ToString
IL_001C: call System.Console.WriteLine
IL_0021: nop
IL_0022: ldc.i4.0
IL_0023: box System.Int32
IL_0028: stloc.2
IL_0029: ldloc.2
IL_002A: ldnull
IL_002B: callvirt System.Object.Equals
IL_0030: box System.Boolean
IL_0035: stloc.1
IL_0036: ldstr "b={0}"
IL_003B: ldloc.1
IL_003C: callvirt System.Object.ToString
IL_0041: call System.Console.WriteLine
IL_0046: nop
Run Code Online (Sandbox Code Playgroud)
如您所见,区别在于调用Equals的实现.在第一种情况下,调用Int32.Equals(Int32是一个CLR结构).这是一个价值对等检查.
在第二个实例中,调用Object.Equals进行引用比较 - 引用是否指向同一个对象?
您不应期望这些方法具有相同的行为.
我建议你要问问自己为什么要将整数与Nothing进行比较?它们永远不会是虚无,但对象可以,所以系统的行为是完全合适的.
同样,整数也不可能是什么.将它与Nothing进行比较几乎毫无意义 - 除了CLR类型系统有一个Equals必须返回一些东西的契约.
所以你应该做的是重新分析你正在做的事情,这样你永远不会将普通整数与Nothing进行比较,也绝不会通过程序或函数的形式参数来强制虚假框.相反,按值将它们作为整数传递,这样就不会发生拳击.
如果你绝对肯定要做到这一点,有两个重载.
Private Function EqualsNothing(ByVal item As Integer) As Boolean
Private Function EqualsNothing(ByVal item As Object) As Boolean
Run Code Online (Sandbox Code Playgroud)
CLR语义将优先选择非盒装整数.
我是在凌晨3点写的,所以不检查上面的VB语法细节,因为这是对评论讨论的回应.
或者只是强制将事物取消装箱:
Private Function EqualsNothing(ByVal item As Object) As Boolean
Dim int As Integer = item
Return int.Equals(Nothing)
End Function
Run Code Online (Sandbox Code Playgroud)
再次,它的晚期语法没有检查.这样做的风险是,如果对象不是整数,则会出现异常.
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |