3

Nothing after a New, is it possible?

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

Is there a theoretical possibility that the constructor returns a null (Nothing) Object?

Say, to set Me = Nothing in the constructor? Or if an exception is thrown in constructor, what happens in the catch with the object? Or in the last constructor line I pass by reference "Me" to a method and this method sets that reference to Nothing?

serhio
  • 28,010
  • 62
  • 221
  • 374
  • I would think that either the MyClass constructor will throw an exception (which if it isn't handled will stop execution) or the constructor will return and a new instance of MyClass gets assigned to myObj. – Matt Jan 22 '13 at 16:22
  • 2
    No, I don't think `new` will ever return `null`/`nothing` – asawyer Jan 22 '13 at 16:23
  • possible duplicate of [Can object constructor return a null?](http://stackoverflow.com/questions/438325/can-object-constructor-return-a-null) – Ken Pespisa Jan 22 '13 at 16:28
  • 1
    @KenPespisa: Even if it's not likely, it could be possible that VB.NET behaves differently than C#, hence i would not call it a duplicate (note that even `Nothing` and `null` are rather different). – Tim Schmelter Jan 22 '13 at 16:45

2 Answers2

4

No, the New-operator is used to create a new object instance. Even if all the fields of this object would remain Nothing, the instance itself is not Nothing.

Visual Basic Language Specification:

11.10 New Expressions The New operator is used to create new instances of types. ....

11.10.1 Object-Creation Expressions An object-creation expression is used to create a new instance of a class type or a structure type. The type of an object creation expression must be a class type, a structure type, or a type parameter with a New constraint and cannot be a MustInherit class. Given an object creation expression of the form New T(A), where T is a class type or structure type and A is an optional argument list, overload resolution determines the correct constructor of T to call. A type parameter with a New constraint is considered to have a single, parameterless constructor. If no constructor is callable, a compile-time error occurs; otherwise the expression results in the creation of a new instance of T using the chosen constructor. If there are no arguments, the parentheses may be omitted. Where an instance is allocated depends on whether the instance is a class type or a value type. New instances of class types are created on the system heap, while new instances of value types are created directly on the stack. An object-creation expression can optionally specify a list of member initializers after the constructor arguments. These member initializers are prefixed with the keyword With, and the initializer list is interpreted as if it was in the context of a With statement.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Is it possible to set Me = Nothing in the constructor? Or if an exception is thrown in constructor, what happens? Or if I pass by reference "Me" to a method and this method sets that reference to Nothing? – serhio Jan 23 '13 at 11:13
1

Unless you use On Error Resume Next and there is an exception in the MyClass constructor, or you create a proxy that returns Nothing on creation.

While confirming the VB.NET version of the proxy "works", I noticed myObj Is Nothing is False immediately after creation (like you've asked for in the OP), and yet when you try to do anything else with it, it certainly looks like Nothing. And it normally becomes Nothing once you've tried to do much more with it than test it for a value. (At this stage it's the same with C#. And at this point I should really start a new question...)

But I've found that the presence of an "empty" Try Catch is enough for VB.NET to crystallise the Nothing! (As of the Roslyn C# 6 (Beta) version of LinqPad, C# performs the same.)

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

Note the call to ToString is meant to be commented out: when it is not the Nothing is crystallised as 'expected'.

(Until the Roslyn C# 6-based LinqPad I didn't see a similar effect in C#. I.e. just commenting out the ToString call within the try was enough for myObj to remain non-null. The C# 6 LinqPad (Beta) performs the same as VB.NET, requiring the try to be removed to not have the null crystallised.)

Community
  • 1
  • 1
Mark Hurd
  • 10,665
  • 10
  • 68
  • 101
  • so, this is possible after an exception, or maybe byreference "annulation" by an other method.... – serhio Jan 23 '13 at 11:19
  • 1
    I didn't mention it in the answer because I haven't found the reference to confirm it, but, yes, I think I've previously seen "interesting" code with proxy constructors returning `Nothing`. – Mark Hurd Jan 23 '13 at 11:24
  • Found it! Only from the most upvoted answer of the infamous [What's the strangest corner case you've seen in C# or .NET?](http://stackoverflow.com/a/194671/256431)! – Mark Hurd Jan 24 '15 at 16:05
  • BTW The `instance` _is_ immediately `Nothing` in the generic method case from the "strangest corner case" answer in C# and VB.NET. – Mark Hurd Feb 14 '15 at 11:49