views:

131

answers:

2

It seems like overkill to set the value of a nullable type and implement iNotifyPropertyChanged. Is there a better way of doing this?

        Private _WorkPhone As Long?
    Public Property [WorkPhone]() As Long?
        Get
            Return _WorkPhone
        End Get
        Set(ByVal value As Long?)
            If value.HasValue = False Then
                If _WorkPhone.HasValue = True Then
                    MyBase.RaisePropertyChanging("WorkPhone")
                    _WorkPhone = Nothing
                    MyBase.MarkDirty()
                    MyBase.RaisePropertyChanged("WorkPhone")
                End If
            Else
                If _WorkPhone.HasValue Then
                    If _WorkPhone.Value <> value.Value Then
                        MyBase.RaisePropertyChanging("WorkPhone")
                        _WorkPhone = value
                        MyBase.MarkDirty()
                        MyBase.RaisePropertyChanged("WorkPhone")
                    End If
                Else
                    MyBase.RaisePropertyChanging("WorkPhone")
                    _WorkPhone = value
                    MyBase.MarkDirty()
                End If
                MyBase.RaisePropertyChanged("WorkPhone")
            End If
        End Set
    End Property

I tried using simple code, but my breakpoint on MyBase.RaisePropertyChanging("WorkPhone") is never hit, and the value never changes.

    If _WorkPhone <> value Then
    MyBase.RaisePropertyChanging("WorkPhone")
    _WorkPhone = value
    MyBase.MarkDirty()
    MyBase.RaisePropertyChanged("WorkPhone")
End If
+3  A: 

There is no need for all the complicated logic. If x and y are both nullables with the same underlying type then x equals y if and only if

  1. x.HasValue is true
  2. y.HasValue is true
  3. x.Value equals y.Value

or

  1. x.HasValue is false
  2. y.HasValue is false

In neither of these cases would we want to raise a property changed notification and thus a simple test for non-equality will suffice. Thus:

Private _WorkPhone As Long?
    Public Property [WorkPhone]() As Long?
        Get
            Return _WorkPhone
        End Get
        Set(ByVal value As Long?)
            If Not _workPhone.Equals(value)
                MyBase.RaisePropertyChanging("WorkPhone")
                _WorkPhone = value
                MyBase.MarkDirty()
                MyBase.RaisePropertyChanged("WorkPhone")
            EndIf
        End Set
    End Property

Note that we ned to use Not Nullable(Of T).Equals instead of <> as the latter evaluates to Nothing if one if its operands is Nothing.

Jason
This is exactly the code I was using, but in the postback from asp.net, it was not getting to the first mybase.raisepropertychanging call. It was not setting the value, hence the complicated logic.
Rick Ratayczak
@Rick Ratayczak: What were the values of `_workPhone` and `value` in that case? Unless we're both overlooking something subtle, the above should be correct.
Jason
_workphone.hasvalue = false, and value.hasvalue = trueI am passing in a phone number, to a property without.
Rick Ratayczak
Okay, use `Not _workPhone.Equals(value)` instead of `_workPhone <> value` and you should be fine. The operator `<>` evalues to `Nothing` when one of its operands is `Nothing`; this is why you need to use `Object.Equals` which is overrode for `Nullable(Of T)` to behave correctly.
Jason
Ok, I officially love you, but in a bromance kinda way. lol Thanks for this fix!
Rick Ratayczak
Thank you for adding a new word to my vocabulary. I had never heard the word "bromance" before.
Jason
+1  A: 

As an aside...I notice you are using a LONG to store the work phone number. Even unsigned this will fail above areacode 429 in the U.S. You might consider DOUBLE or STRING

ddzikot
Thanks, I appreciate the feedback. This is coming from Entity Framework, so I'll change the DB.
Rick Ratayczak