You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET监听多层嵌套对象mass属性变更并触发总质量重算的实现方案

需求说明

现有简化代码结构如下:

Public Class Main
    Public world As World
    Public totalWorldMass As Double

    '任意world内对象的mass变更时,需调用该方法
    Sub RecalculateTotalMass()
        totalWorldMass = world.object1.mass + world.object2.mass + world.object3.mass
    End Sub
End Class

Public Class World
    Public Property object1 As objectWithMass
    Public Property object2 As objectWithMass
    Public Property object3 As objectWithMass

    '其他属性和方法
End Class

Public Class ObjectWithMass
    Public Property name As String
    Public Property mass As Double

    '其他属性和方法
End Class

核心要求:Main类监听world实例,只要World中任意ObjectWithMass类型对象的mass属性发生变更,就执行RecalculateTotalMass方法,无需逐个指定监听对象,不借助反射实现。


实现方案

步骤1:给ObjectWithMass实现INotifyPropertyChanged接口

将事件触发逻辑封装在mass属性的setter中,只有mass变更时才触发事件,减少不必要的计算:

Imports System.ComponentModel

Public Class ObjectWithMass
    Implements INotifyPropertyChanged

    Private _name As String
    Private _mass As Double

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Public Property name As String
        Get
            Return _name
        End Get
        Set(value As String)
            _name = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(name)))
        End Set
    End Property

    Public Property mass As Double
        Get
            Return _mass
        End Get
        Set(value As Double)
            _mass = value
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(mass)))
        End Set
    End Property

    '其他属性和方法
End Class

步骤2:在World类中封装统一的MassChanged事件

将子对象的监听逻辑封装在World内部,对外只暴露统一的质量变更事件,自动处理子对象引用更换的场景:

Imports System.ComponentModel

Public Class World
    Private _object1 As ObjectWithMass
    Private _object2 As ObjectWithMass
    Private _object3 As ObjectWithMass

    '对外暴露的统一事件,所有子对象mass变更都会触发该事件
    Public Event MassChanged As EventHandler

    Public Property object1 As ObjectWithMass
        Get
            Return _object1
        End Get
        Set(value As ObjectWithMass)
            '移除旧对象的监听
            If _object1 IsNot Nothing Then
                RemoveHandler _object1.PropertyChanged, AddressOf HandleChildMassChanged
            End If
            _object1 = value
            '给新对象添加监听
            If _object1 IsNot Nothing Then
                AddHandler _object1.PropertyChanged, AddressOf HandleChildMassChanged
            End If
        End Set
    End Property

    'object2、object3写法和object1完全一致
    Public Property object2 As ObjectWithMass
        Get
            Return _object2
        End Get
        Set(value As ObjectWithMass)
            If _object2 IsNot Nothing Then
                RemoveHandler _object2.PropertyChanged, AddressOf HandleChildMassChanged
            End If
            _object2 = value
            If _object2 IsNot Nothing Then
                AddHandler _object2.PropertyChanged, AddressOf HandleChildMassChanged
            End If
        End Set
    End Property

    Public Property object3 As ObjectWithMass
        Get
            Return _object3
        End Get
        Set(value As ObjectWithMass)
            If _object3 IsNot Nothing Then
                RemoveHandler _object3.PropertyChanged, AddressOf HandleChildMassChanged
            End If
            _object3 = value
            If _object3 IsNot Nothing Then
                AddHandler _object3.PropertyChanged, AddressOf HandleChildMassChanged
            End If
        End Set
    End Property

    '内部处理子对象的属性变更事件
    Private Sub HandleChildMassChanged(sender As Object, e As PropertyChangedEventArgs)
        If e.PropertyName = NameOf(ObjectWithMass.mass) Then
            RaiseEvent MassChanged(Me, EventArgs.Empty)
        End If
    End Sub

    '其他属性和方法
End Class

步骤3:在Main类中绑定World的统一事件

Public Class Main
    '给world添加WithEvents关键字
    Public WithEvents world As World
    Public totalWorldMass As Double

    Sub RecalculateTotalMass()
        totalWorldMass = world.object1.mass + world.object2.mass + world.object3.mass
    End Sub

    '直接绑定world的MassChanged事件即可
    Private Sub HandleWorldMassChanged() Handles world.MassChanged
        RecalculateTotalMass()
    End Sub
End Class

方案特点

  • 无反射依赖,性能表现更好
  • 无需在Main类中逐个绑定子对象事件,后续World新增带mass的属性时,Main代码无需改动
  • 自动适配子对象引用更换的场景,不会出现事件漏触发问题

内容的提问来源于stack exchange,提问作者Justin8051

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:36:02