C# INotifyPropertyChanged为空的类型和属性

C# INotifyPropertyChanged为空的类型和属性,c#,vb.net,nullable,inotifypropertychanged,C#,Vb.net,Nullable,Inotifypropertychanged,设置可为null的类型的值并实现iNotifyPropertyChanged似乎有些过分。有更好的方法吗 Private _WorkPhone As Long? Public Property [WorkPhone]() As Long? Get Return _WorkPhone End Get Set(ByVal value As Long?) If value.HasVa

设置可为null的类型的值并实现iNotifyPropertyChanged似乎有些过分。有更好的方法吗

        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
Private\u工作电话有多长?
公共财产[工作电话]()有多长?
得到
返回工作电话
结束
设置(ByVal值是否长?)
如果value.HasValue=False,则
如果_WorkPhone.HasValue=True,则
MyBase.RaisePropertyChange(“工作电话”)
_工作电话=无
MyBase.MarkDirty()
MyBase.RaisePropertyChanged(“工作电话”)
如果结束
其他的
如果_WorkPhone.HasValue,则
如果_WorkPhone.Value.Value然后
MyBase.RaisePropertyChange(“工作电话”)
_工作电话=值
MyBase.MarkDirty()
MyBase.RaisePropertyChanged(“工作电话”)
如果结束
其他的
MyBase.RaisePropertyChange(“工作电话”)
_工作电话=值
MyBase.MarkDirty()
如果结束
MyBase.RaisePropertyChanged(“工作电话”)
如果结束
端集
端属性
我尝试使用简单的代码,但我在MyBase.raisePropertyChange(“WorkPhone”)上的断点从未命中,并且值也从未更改

    If _WorkPhone <> value Then
    MyBase.RaisePropertyChanging("WorkPhone")
    _WorkPhone = value
    MyBase.MarkDirty()
    MyBase.RaisePropertyChanged("WorkPhone")
End If
If\u工作电话值然后
MyBase.RaisePropertyChange(“工作电话”)
_工作电话=值
MyBase.MarkDirty()
MyBase.RaisePropertyChanged(“工作电话”)
如果结束

不需要所有复杂的逻辑。如果
x
y
都是具有相同基础类型的可空值,则
x
等于
y
当且仅当

  • x.HasValue
    true
  • y.HasValue
    true
  • x.Value
    等于
    y.Value
  • x.HasValue
    false
  • y.HasValue
    false
  • 在这两种情况下,我们都不希望发出属性更改通知,因此一个简单的不平等测试就足够了。因此:

    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
    

    请注意,我们需要使用
    不可为空(T的)。Equals
    而不是
    ,因为后者的计算结果为
    ,如果一个操作数为

    ,则不需要所有复杂的逻辑。如果
    x
    y
    都是具有相同基础类型的可空值,则
    x
    等于
    y
    当且仅当

  • x.HasValue
    true
  • y.HasValue
    true
  • x.Value
    等于
    y.Value
  • x.HasValue
    false
  • y.HasValue
    false
  • 在这两种情况下,我们都不希望发出属性更改通知,因此一个简单的不平等测试就足够了。因此:

    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
    

    请注意,如果一个操作数为
    Nothing
    ,的话,我们需要使用
    Not Nullable(Of T).Equals来代替
    ,因为后者的计算结果为
    Nothing
    ,如果一个操作数为
    Nothing

    作为旁白…我注意到您正在使用LONG来存储工作电话号码。即使在美国中AcAcCODE 429以上的UncDebug将失败,您可能会考虑双倍或String

    作为旁白……我注意到您正在使用一个长的来存储工作电话号码。即使在美国中AcAcCODE 429以上的UncDebug将失败,您可能会考虑双倍或String

    这正是我使用的代码,但是在ASP.NET的回发中,它没有到达第一个MyBaseRaSeAsvyTyTrchange调用。它没有设置值,因此逻辑很复杂。@Rick Ratayczak:在这种情况下,
    \u workPhone
    value
    的值是什么?除非我们都忽略了一些微妙的事情,否则上面的说法应该是正确的。_workphone.hasvalue=false,value.hasvalue=true我正在将一个电话号码传递给一个没有。好的,用
    而不是
    代替
    \u workphone value
    ,你应该没事。当操作符的一个操作数为
    Nothing
    时,操作符
    求值为
    Nothing
    ;这就是为什么你需要使用
    Object.Equals
    ,它被
    Nullable(Of T)
    覆盖,这样才能正确地表现。好吧,我正式地爱你,但有点像bromance。哈哈,谢谢你的修复!这正是我使用的代码,但是在asp.net的回发中,它没有到达第一个mybase.RaisePropertyChange调用。它没有设置值,因此逻辑很复杂。@Rick Ratayczak:在这种情况下,
    \u workPhone
    value
    的值是什么?除非我们都忽略了一些微妙的事情,否则上面的说法应该是正确的。_workphone.hasvalue=false,value.hasvalue=true我正在将一个电话号码传递给一个没有。好的,用
    而不是
    代替
    \u workphone value
    ,你应该没事。当操作符的一个操作数为
    Nothing
    时,操作符
    求值为
    Nothing
    ;这就是为什么你需要使用
    Object.Equals
    ,它被
    Nullable(Of T)
    覆盖,这样才能正确地表现。好吧,我正式地爱你,但有点像bromance。哈哈,谢谢你的修复!谢谢,谢谢你的反馈。这是来自实体框架,所以我将更改数据库。谢谢,我感谢您的反馈。这来自实体框架,因此我将更改数据库。