views:

197

answers:

5

In VB.NET, why can't I see a member of a structure when I make it a nullable type?

Example:

Public Structure myNullable  
    Dim myNullVar As Integer  
End Structure

Sub Main()  
    Dim myInstance As myNullable 'This works.  
    Dim myNullableInstance? As myNullable 'This works.   
    myInstance.myNullVar = 1  'This works.     
    myNullableInstance.myNullVar = 1   'This doesn't work.  
End Sub
A: 

When a type is nullable you are supposed to be checking to see if it has a value, then accessing that value only if there is one:

if(myNullableInstance.hasValue)
myNullableInstance.value.myNullVar=1
Maslow
I get this error when I try that: "Expression is a value and therefore cannot be the target of an assignment."
Pliskin
yeah it appears my knowledge of structures is nearly non-existent since the switch to object orientation. Respond to my questions commented off of the base post?
Maslow
Love the sarcasm.
Pliskin
I don't think anything I said was sarcastic. If it came off as snide or something, I apologize. I haven't had any good experiences, or had any place I saw a struct in code and left it there in my time programming with .net.
Maslow
+1  A: 

Because the Nullable<T> structure exposes the underlying value via the Value property. Therefore, you need:

myNullableInstance.Value.myNullVar = 1

HTH, Kent

Kent Boogaart
I get this error when I try that: "Expression is a value and therefore cannot be the target of an assignment."
Pliskin
+2  A: 

As others have said, you need to use the Value property to fetch the value. However, System.Nullable<T> is immutable - the Value property is read-only. It will be returning a copy of the value, so even if you could change the field, it wouldn't do what you want.

This is actually a good thing - value types should be immutable. Mutable structs are horrible - if the fact that Nullable<T> makes it hard to use your type pushes you down the immutability route, that's great.

Make your field read-only, and add a constructor to let you pass in the value. Then instead of trying to modify the nullable value, assign an entirely new value to the variable.

Jon Skeet
Ah bizarre struct issues, another reason I don't like structs.
Maslow
While I rarely write structs myself, the problem is really with *mutable* structs here.
Jon Skeet
I've had mutable structs bite me before, and since I had no idea what was going on... I switched the word structure to class. and all the sudden all my code worked. So I abandoned trying structs.
Maslow
A: 

As other answers have noted, you can access the inner value of a nullable with .Value. But they suggest you to do myNullableInstance.Value.myNullVar = 1 which doesn't work.

That's because of the way structures work. When you change a member of a struct, a new struct instance is created. You can't do that in this case because it would modify the Value property of the Nullable class, which can't be done directly, because Value is ReadOnly.

This would work though:

Dim myInstance as myNullable
myInstance.myNullVar = 1
myNullableInstance = myInstance
Meta-Knight
A: 

It makes sense that this does not work: myNullableInstance.Value.myNullVar = 1

Basically, you would be assigning to some copy of the structure that was returned by the Value property.

It's not really a problem, because usually structures are made to be immutable as a best practise. You could work around this with some assignments back and forth, but as others have posted, you should reconsider using a class instead. That way, you don't need any Nullable either, because you can just use a null reference.

Thorarin