Setting value types to Nothing?

Why in the world does VB.NET let you assign 'Nothing' to a value type? It's not that big of a deal unless you've got a structure. Consider this simple structure:

Structure ABC
    Dim first As Integer
    Dim second As String
End Structure

For some really odd reason (I haven't googled for this yet), the following code is legal in VB.NET and compiles:

Dim o As ABC = Nothing

Does the code act any differently that if I hadn't set it to nothing? Not really. Unless you look at the IL. Setting that variable 'o' (a structure) to Nothing produces the following IL:

  .locals init ([0] valuetype NothingValue.Module1/ABC o)
  IL_0000:  nop
  IL_0001:  ldnull
  IL_0002:  dup
  IL_0003:  brtrue.s   IL_0015
  IL_0005:  pop
  IL_0006:  ldtoken    NothingValue.Module1/ABC
  IL_000b:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_0010:  call       object [mscorlib]System.Activator::CreateInstance(class [mscorlib]System.Type)
  IL_0015:  unbox      NothingValue.Module1/ABC
  IL_001a:  ldobj      NothingValue.Module1/ABC
  IL_001f:  stloc.0

Yikes!! I'm no IL expert by any means, but what the heck is all of that? I've browsed through the OpCodes class to try and figure out some hidden meaning behind this and it hasn't hit me yet. I mean, look at those first few instructions -- pushing a null onto the evaluation stack, duplicating it and then checking if that is true? I'm sure this would get optmized out by the JIT, but having to go through a Activator.CreateInstance along with an unboxing seems a little excessive.

Finally, I don't want to make this into a language war, but C# won't even let you compile code that tries to set a value type to null.

ABC o = null;

Error!

Cannot convert null to 'Class1.ABC' because it is a value type

2 Comments

  • I think it's setting each member to their default value. I'm not VB expert, so I may be wrong...

  • A static member could be a possible solution... depending on the context of the problem you want to solve, of course.



    struct Abc

    {

    static Abc Empty = Abc.CreateEmpty();

    int first;

    string second;

    ... other code ...

    }



    The CreateEmpty method is usually a private one where you give each member a value. Of course be carefull about the values - they must be one-of-its-kind to avoid unwanted accidental instance equality with the Empty one :)





    Optional you can override the Equals method(or the '=' operator) to be able to compare two Abc instances and check for an Empty one.



    Regards!



Comments have been disabled for this content.