views:

1220

answers:

3

I have a nullable public property on a class using Vb.net 3.5:

    Public Property TicketCharge() As Nullable(Of Decimal)
        Get
            If _TicketCharge = Nothing Then
                Return Nothing
            Else
                Return _TicketCharge
            End If
        End Get
        Set(ByVal value As Nullable(Of Decimal))
            If value.HasValue Then _TicketCharge = value
        End Set
    End Property

There's a method that assigns the value. It works fine, except for when I try to assign the value 0 (zero) to it.

    If FundBuySell = "Exchange $" Or FundBuySell = "Exchange Shares" Then
            TicketCharge = 0
    Else

When I assign zero and then retrieve it, it shows the property = nothing.

I need the property to be Null sometimes and Zero sometimes. Can someone explain what is going on?

+1  A: 

The If _TicketCharge = Nothing is not doing what you expect (inflammatory comment: as it always is with VB.NET; sorry guys, couldn't resist it). You either need If _TicketCharge Is Nothing or If Not _TicketCharge.HasValue

Anton Gogolev
if I use _TicketCharge Is Nothing, I get this error: "Is operator does not accept operands of type Decimal. Operands must be reference or nullable types."If I use _TicketCharge.HasValue, I get this error: "HasValue is not a member of Decimal"
theminesgreg
You never told that your _TicketCharge is Decimal, not Nullable(Of Decimal).
Anton Gogolev
I don't understand. It is Nullable(of Decimal) -- as shown above. All I changed was "_TicketCharge = Nothing" to "_TicketCharge Is Nothing".
theminesgreg
I got it! Sorry. A little slow sometimes.
theminesgreg
A: 

To explain further:

Nothing pulls double duty in VB.Net as both the "null" value for reference types and the "default" value for value types. When you use "=" rather than "Is" or "HasValue", you're forcing it into the value-type role, and so the Nullable class will compare it to it's current stored value (including throwing an exception if no value is set!). Since the default value of a Decimal is 0, the comparison at the top of your Get accessor evaluates to True.

Joel Coehoorn
+1  A: 

The problem is the way that you are comparing _TicketChange in order to determine if it has a value. Nothing has several meanings in VB.Net as it represents both an empty value and reference type. Doing boolean logic with Nothing and a Nullable will lead to often unexpected behavior.

Instead use _TicketChange.HasValue.

JaredPar