3

Nothing之后New,有可能吗?

Dim myObj As MyClass = Nothing
myObj = New MyClass(params)
If myObj Is Nothig Then
  ' is it possible?
End If

构造函数返回一个空(无)对象是否存在理论上的可能性?

说,Me = Nothing在构造函数中设置?或者,如果在构造函数中抛出异常,对象的 catch 中会发生什么?或者在最后一个构造函数行中,我通过引用“Me”传递给一个方法,而这个方法将该引用设置为 Nothing?

4

2 回答 2

4

不,New-operator用于创建新的对象实例。即使该对象的所有字段都将保留Nothing,实例本身也不会保留Nothing

Visual Basic 语言规范:

11.10 新表达式New 运算符用于创建类型的新实例。……

11.10.1 对象创建表达式对象创建表达式用于创建类类型或结构类型的新实例。对象创建表达式的类型必须是类类型、结构类型或具有 New 约束的类型参数,不能是 MustInherit 类。给定 New T(A) 形式的对象创建表达式,其中 T 是类类型或结构类型,A 是可选参数列表,重载决策确定要调用的 T 的正确构造函数。具有 New 约束的类型参数被认为具有单个无参数构造函数。如果没有可调用的构造函数,则会发生编译时错误;否则,表达式会导致使用所选构造函数创建 T 的新实例。如果没有参数,括号可以省略。分配实例的位置取决于实例是类类型还是值类型。类类型的新实例在系统堆上创建,而值类型的新实例直接在栈上创建。对象创建表达式可以选择在构造函数参数之后指定成员初始值设定项列表。这些成员初始化器以关键字 With 为前缀,初始化器列表被解释为好像它位于 With 语句的上下文中。

于 2013-01-22T16:24:24.287 回答
1

除非您使用On Error Resume Next并且构造函数中存在异常MyClass,或者您创建了一个在创建时返回的代理Nothing

在确认代理的 VB.NET 版本“有效”时,我注意到myObj Is Nothing它是False在创建之后立即发生的(就像您在 OP 中要求的那样),但是当您尝试用它做任何其他事情时,它肯定看起来像Nothing. Nothing一旦你尝试用它做更多而不是测试它的价值,它通常会变成。(在这个阶段它与 C# 相同。在这一点上我真的应该开始一个新问题......)

但我发现“空”的存在Try Catch足以让 VB.NET 将Nothing! (从 LinqPad 的 Roslyn C# 6 (Beta) 版本开始,C# 的性能相同。)

Sub Main()
    Dim myObj = New MyFunnyType()
    If myObj Is Nothing Then
      Call "It IS Nothing".Dump
    Else
      ' Comment out this Try and myObj will not be Nothing below.
      Try
        'Call myObj.ToString.Dump
      Catch nr As NullReferenceException
        Call "Maybe it was nothing?".Dump
      Catch ex As Exception
        Call ex.Message.Dump
      End Try
      Call myObj.Dump("Nil?")
      If myObj Is Nothing Then
        Call "Now it IS Nothing".Dump
      Else
        Call "It still is NOT Nothing!".Dump
      End If
    End If
End Sub

' Define other methods and classes here
Class MyFunnyProxyAttribute
  Inherits ProxyAttribute
    Public Overrides Function CreateInstance(ByVal ServerType As Type) As MarshalByRefObject
        Return Nothing
    End Function
End Class

<MyFunnyProxy> _
Class MyFunnyType
  Inherits ContextBoundObject
  Public Overrides Function ToString() As String
    If Me IsNot Nothing Then
      Return "Yes, I'm here!"
    Else
      Return "No, I'm really Nothing!"
    End If
  End Function
End Class

请注意,调用ToString是要被注释掉的:当它不是时,它Nothing被结晶为“预期的”。

(在基于 Roslyn C# 6 的 LinqPad 之前,我在 C# 中没有看到类似的效果。即仅在 中注释掉ToString调用try就足以myObj保持非null.C# 6 LinqPad(Beta)的性能与 VB.NET 相同, 要求try将 去除以不null结晶。)

于 2013-01-23T09:54:15.367 回答