“foo = Nothing” 和有什么不一样?和“foo 没什么”在 VB.NET 中?

发布于 2024-09-07 04:50:53 字数 834 浏览 3 评论 0原文

有什么区别

if foo is Nothing Then
      doStuff()
End If

VB.NET中,和

if foo=Nothing Then
    doStuff()
End If

更新 我收到以下答复:

foo is Nothing 只是检查 foo 是否未分配给任何引用。 foo = Nothing 检查 foo 持有的引用是否等于 nothing

运行这三个语句后,

Dim foo as Object
Dim bar as Integer
foo = bar

foo is Nothing 的计算结果为 false,foo = Nothing 的计算结果为 true。

但是,如果 bar 被声明为 Object 并且未初始化,则 foo is Nothingfoo = Nothing 两者评价为真!我认为这是因为 Integer 是值类型,而 Object 是引用类型。

In VB.NET, what is the difference between

if foo is Nothing Then
      doStuff()
End If

and

if foo=Nothing Then
    doStuff()
End If

Update I received the following answer:

foo is Nothing simply checks if foo is not assigned to any reference.
foo = Nothing checks if the reference held by foo is equal to nothing.

After running the three statements,

Dim foo as Object
Dim bar as Integer
foo = bar

foo is Nothing evaluates to false and foo = Nothing evaluates to true.

However, if bar is declared as an Object and not initialized, then foo is Nothing and foo = Nothing both evaluate to true! I think this is because Integer is a value type and Object is a reference type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

尹雨沫 2024-09-14 04:50:53

这取决于类型。

  • 对于值类型Is不起作用,仅=Nothing< /code> 指的是该类型的默认实例(即通过为给定类型 T 调用 New T() 获得的实例)。


  • 对于引用类型Is 执行引用比较(与object.ReferenceEquals(a, Nothing) 相同)。 a = Nothing 通常不起作用除非已为该类显式定义Operator =

    此外,如果 Operator = 已正确实现,则 foo = Nothingfoo Is Nothing 应该产生相同的结果(但是对于任何其他值(而不是 Nothing)来说,情况并非如此),但 foo Is Nothing 会更高效,因为它是编译器固有的,而 Operator = > 将调用一个方法。

  • 对于可空值类型(即Nullable(Of T)的实例),适用特殊规则:与所有其他运算符一样,=已提升 (请注意该博客文章中的错误...)由编译器转换为底层类型。因此,比较两个 Nullable 的结果不是 Boolean 而是 Boolean?(注意 ?)。然而,由于提升运算符所谓的“空传播”,无论 foo 的值是什么,这总是返回Nothing。引用 Visual Basic 10 语言规范 (§1.86.3):

    <块引用>

    如果以太(原文如此!)操作数为 Nothing,则表达式的结果为 Nothing 值,键入为结果类型的可为空版本。

    因此,如果用户想要将 Nullable 变量与 Nothing 进行比较,他们必须再次使用 foo Is Nothing 语法,编译器生成特殊代码以使其工作(Visual Basic 10 语言规范的第 1.79.3 节)。
    向乔纳森·艾伦(Jonathan Allen)致敬,他(正确地)坚持认为我错了;感谢 Jared Parsons 向我传递了 Visual Basic 10 规范的链接。

(上面假设使用了 Option Strict On,因为您总是应该这样做如果情况并非如此,结果会略有不同,因为调用 foo = Nothing 可能会执行后期绑定调用。)

It depends on the type.

  • For value types, Is doesn’t work, only =, and Nothing refers to the default instance of that type (i.e. the instance that you get by calling New T() for a given type T).

  • For reference types, Is performs a reference comparison (identical to object.ReferenceEquals(a, Nothing)). a = Nothing usually does not work, unless Operator = has explicitly been defined for that class.

    If, furthermore, Operator = has been implemented correctly, then foo = Nothing and foo Is Nothing should yield the same result (but the same isn’t true for any other value instead of Nothing) but foo Is Nothing will be more efficient since it’s a compiler intrinsic while Operator = will call a method.

  • For nullable value types (i.e. instances of Nullable(Of T)), special rules apply: like all other operators, = is lifted (notice the error in that blog post …) by the compiler to the underlying type. The result of comparing two Nullables is thus not Boolean but Boolean? (note the ?). However, because of so-called “null propagation” for lifted operators, this will always return Nothing, no matter the value of foo. Quoting the Visual Basic 10 language specification (§1.86.3):

    If ether (sic!) operand is Nothing, the result of the expression is a value of Nothing typed as the nullable version of the result type.

    So if the users want to compare a Nullable variable to Nothing, they must use the foo Is Nothing syntax for which, once again, the compiler generates special code to make it work (§1.79.3 of the Visual Basic 10 language specification).
    Hat tip to Jonathan Allen for (correctly) persisting that I was wrong; hat tip to Jared Parsons for passing me a link to the Visual Basic 10 specification.

(The above assumes that Option Strict On is used, as you always should. In case that isn’t the case, the results will differ slightly since calling foo = Nothing may perform a late-bound call.)

涫野音 2024-09-14 04:50:53
foo is Nothing simply checks if `foo` is not assigned to any reference.

foo=Nothing checks if the reference held by `foo` is equal to `nothing`

在 VB 中,如果 foo 尚未初始化,两个语句的计算结果将相同

foo is Nothing simply checks if `foo` is not assigned to any reference.

foo=Nothing checks if the reference held by `foo` is equal to `nothing`

In VB, both statements will evaluate to the same value if foo has not been initialised

野侃 2024-09-14 04:50:53

下面是一些用于验证差异的 IL:

.method public static void Main() cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .entrypoint
    .maxstack 3
    .locals init (
        [0] object o,
        [1] bool VB$CG$t_bool$S0)
    L_0000: nop 
    L_0001: newobj instance void [mscorlib]System.Object::.ctor()
    L_0006: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: ldnull 
    L_000e: ceq 
    L_0010: stloc.1 
    L_0011: ldloc.1 
    L_0012: brfalse.s L_001f
    L_0014: ldstr "Is Nothing"
    L_0019: call void [mscorlib]System.Console::WriteLine(string)
    L_001e: nop 
    L_001f: nop 
    L_0020: ldloc.0 
    L_0021: ldnull 
    L_0022: ldc.i4.0 
    L_0023: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::ConditionalCompareObjectEqual(object, object, bool)
    L_0028: stloc.1 
    L_0029: ldloc.1 
    L_002a: brfalse.s L_0037
    L_002c: ldstr "Is nothing"
    L_0031: call void [mscorlib]System.Console::WriteLine(string)
    L_0036: nop 
    L_0037: nop 
    L_0038: nop 
    L_0039: ret 
}

VB 代码:

Sub Main()
        Dim o As New Object

        If o Is Nothing Then
            Console.WriteLine("Is Nothing")
        End If

        If o = Nothing Then
            Console.WriteLine("Is nothing")
        End If
    End Sub

Here's some IL to validate the differences:

.method public static void Main() cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .entrypoint
    .maxstack 3
    .locals init (
        [0] object o,
        [1] bool VB$CG$t_bool$S0)
    L_0000: nop 
    L_0001: newobj instance void [mscorlib]System.Object::.ctor()
    L_0006: call object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object)
    L_000b: stloc.0 
    L_000c: ldloc.0 
    L_000d: ldnull 
    L_000e: ceq 
    L_0010: stloc.1 
    L_0011: ldloc.1 
    L_0012: brfalse.s L_001f
    L_0014: ldstr "Is Nothing"
    L_0019: call void [mscorlib]System.Console::WriteLine(string)
    L_001e: nop 
    L_001f: nop 
    L_0020: ldloc.0 
    L_0021: ldnull 
    L_0022: ldc.i4.0 
    L_0023: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::ConditionalCompareObjectEqual(object, object, bool)
    L_0028: stloc.1 
    L_0029: ldloc.1 
    L_002a: brfalse.s L_0037
    L_002c: ldstr "Is nothing"
    L_0031: call void [mscorlib]System.Console::WriteLine(string)
    L_0036: nop 
    L_0037: nop 
    L_0038: nop 
    L_0039: ret 
}

VB Code:

Sub Main()
        Dim o As New Object

        If o Is Nothing Then
            Console.WriteLine("Is Nothing")
        End If

        If o = Nothing Then
            Console.WriteLine("Is nothing")
        End If
    End Sub
自控 2024-09-14 04:50:53

foo 是指向内存位置的指针,Nothing 表示“未指向任何内存,因为尚未分配内存”。等于意味着当您比较 2 个值类型时它们具有相同的值。但是您假设 foo 代表一个对象,它始终是一个引用类型,旨在指向内存中的对象。 'is' 用于比较对象类型,并且仅当有两个对象指向相同值时才返回 'true'。

假设您有 clsFoo 和一个公共整数成员变量“x”,并且 foo1 和 foo2 都是 clsFoo,并且 y 和 z 是整数

foo1=new clsFoo
foo2=new clsFoo
foo1.x=1
foo2.x=1
y=2
z=1
dim b as boolean 

b= foo1 is not foo2  ' b is true
b= foo1.x=foo2.x ' b is tree
b= foo1 is foo2 'b is false  
b= foo1.x=z ' true of course
foo2.x=3
b= foo1.x=foo2.x ' false of course
foo1=foo2
b=foo1 is foo2 ' now it's true
b= foo1.x=foo2.x ' true again
b= 3=3 ' just as this would be
b= foo1=foo2 ' ERROR: Option Strict On disallows operands of type Object for operator '='. Use the 'Is' operator to test for object identity.

永远不要忘记打开 option strict。如果失败了,那就是尖叫“请让我的程序糟透了。”

foo is a pointer to a memory location and Nothing means 'not pointing to any memory because no memory has been allocated yet'. Equals means that when you are comparing 2 value types they have the same value. But you're assuming foo represents an object, which is always a reference type that is meant to point to an object in memory. 'is' is for comparing object types and will only return 'true' if you have two objects pointing to the same value.

Say you have clsFoo with one public integer member variable 'x' and foo1 and foo2 are both clsFoo, and y and z are integers

foo1=new clsFoo
foo2=new clsFoo
foo1.x=1
foo2.x=1
y=2
z=1
dim b as boolean 

b= foo1 is not foo2  ' b is true
b= foo1.x=foo2.x ' b is tree
b= foo1 is foo2 'b is false  
b= foo1.x=z ' true of course
foo2.x=3
b= foo1.x=foo2.x ' false of course
foo1=foo2
b=foo1 is foo2 ' now it's true
b= foo1.x=foo2.x ' true again
b= 3=3 ' just as this would be
b= foo1=foo2 ' ERROR: Option Strict On disallows operands of type Object for operator '='. Use the 'Is' operator to test for object identity.

NEVER forget to turn option strict on. To fail this is to scream 'PLEASE make my program SUCK.'

眼眸里的快感 2024-09-14 04:50:53

假设:

MyFunc(Foo 作为对象)

Foo - 如果 ValueType 则装箱

如果 foo 是 Nothing 那么

object.ReferenceEquals(内联代码 - 最快的方法)

if foo=Nothing then

Operators.ConditionalCompareObjectEqual(foo, Nothing, False)

Vb.Net 携带这种情况,如 Obj1 = Obj2。
它不使用 Obj.equals(obj2) !如果 Obj1 没有任何异常,则

此选项使用非常复杂的代码,因为有很多选项取决于所有可能的 foo 定义。

试试这个:

子主函数()
  变暗 o 作为对象 = 0
  Debug.Print(o 什么也没有) 'False
  Debug.Print(o = Nothing) 'True 
结束子

Asume:

MyFunc(Foo as object)

Foo - Boxed if ValueType

if foo is Nothing Then

object.ReferenceEquals (Code Inlined - Fastest method)

if foo=Nothing Then

Operators.ConditionalCompareObjectEqual(foo, Nothing, False)

Vb.Net carry this case like Obj1 = Obj2.
It do´nt uses Obj.equals(obj2) ! Exception if Obj1 is nothing

This option uses a very complex code as there are a lot options depending all posible foo definitions.

try this:

Sub Main()
  Dim o As Object = 0
  Debug.Print(o Is Nothing)  'False
  Debug.Print(o = Nothing)   'True 
End Sub
温暖的光 2024-09-14 04:50:53

这取决于 Foo 的类型。

引用类型

if foo = Nothing then 'This depends on how the op_Equals operator is defined for Foo. If not defined, then this is a compiler error. 
if foo Is Nothing then 'Evaluates to True is foo is NULL

值类型

if foo = Nothing then 'Evaluates to True is foo has the default value in every field. For most types the default is 0.
if foo Is Nothing then 'Compiler Error

可空值类型

if foo = Nothing then 'This always evaluates to false. In VB 10, this is a compiler warning
if foo Is Nothing then 'Evaluates to True is foo.HasValue = False

很多人不理解 VB 中的空传播。与 SQL 一样,它使用三值逻辑,因此“a=b”的答案可能是 True、False 或 Null。在 If 语句中,Null 被视为 False。

警告你不能只写If Not(Foo = Nothing) then,因为“Not (Nothing)”仍然是“Nothing”。

It depends on Foo's type.

Reference Types

if foo = Nothing then 'This depends on how the op_Equals operator is defined for Foo. If not defined, then this is a compiler error. 
if foo Is Nothing then 'Evaluates to True is foo is NULL

Value Types

if foo = Nothing then 'Evaluates to True is foo has the default value in every field. For most types the default is 0.
if foo Is Nothing then 'Compiler Error

Nullable Value Types

if foo = Nothing then 'This always evaluates to false. In VB 10, this is a compiler warning
if foo Is Nothing then 'Evaluates to True is foo.HasValue = False

A lot of people don't understand Null Propogation in VB. Like SQL, it uses three-value logic so the answer for "a=b" could be True, False, or Null. In an If statement a Null is treated as a False.

Warning You can't just write If Not(Foo = Nothing) Then because 'Not (Nothing)' is still 'Nothing'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文