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

C#实现继承自List<>的Dimensions类内部Dimension对象变更事件相关问题

现有代码核心问题
  • Dimension类Id属性set访问器存在参数错误:Id修改时错误传入了_Size作为事件参数,无法正确传递Id的变更值
  • Dimensions类OnRemoved方法逻辑错误:错误触发了添加事件的委托,不会触发移除对应的事件
  • 缺失单个Dimension对象的属性变更订阅逻辑:添加Dimension对象时没有绑定其内部变更事件,移除时也没有取消订阅,导致对象内部属性修改时Dimensions类无法感知
  • 重写List的Add/Remove方法使用new关键字存在局限:如果将Dimensions实例转为父类List<Dimension>调用Add/Remove,事件不会触发,建议优先选择继承Collection<Dimension>实现更规范的集合扩展
修正后完整实现代码
namespace Autozite.Entities
{
    // 基础事件参数类,你项目如果已有实现可直接复用
    public class xEventArgs<T> : EventArgs
    {
        public T Data { get; }
        public xEventArgs(T data)
        {
            Data = data;
        }
    }

    public delegate void DimensionInsideChangeEventHandler(Dimension sender, xEventArgs<int> e);

    public class Dimension
    {
        private int _Id;

        public int Id
        {
            get { return _Id; }
            set 
            { 
                _Id = value; 
                // 修复参数错误,传递当前修改的Id值
                OnChange(new xEventArgs<int>(_Id)); 
            }
        }
        private int _Size;

        public int Size
        {
            get { return _Size; }
            set 
            { 
                _Size = value; 
                OnChange(new xEventArgs<int>(_Size)); 
            }
        }
        #region Event On Method
        public event DimensionInsideChangeEventHandler DimensionChange;
        protected virtual void OnChange(xEventArgs<int> e)
        {
            DimensionChange?.Invoke(this, e);
        }
        #endregion
    }
}

namespace Autozite.Entities
{
    public delegate void DimensionAddedEventHandler(Dimensions sender, xEventArgs<Dimension> e);
    public delegate void DimensionRemovedEventHandler(Dimensions sender, xEventArgs<Dimension> e);
    public delegate void DimensionChangeEventHandler(Dimensions sender, xEventArgs<Dimension> e);

    // 建议替换为继承Collection<Dimension>,可避免new关键字重写的局限性
    public class Dimensions : List<Dimension>
    {
        public Dimensions()
        {
        }

        // 实现单个Dimension属性变更的处理逻辑,向上抛出集合层级的事件
        private void Dimensions_DimensionChange(Dimension sender, xEventArgs<int> e)
        {
            OnChange(new xEventArgs<Dimension>(sender));
        }

        // 修正原委托名称拼写错误
        public event DimensionAddedEventHandler DimensionAdded;
        public event DimensionRemovedEventHandler DimensionRemoved;
        public event DimensionChangeEventHandler DimensionChange;

        public new void Add(Dimension dimension)
        {
            if (dimension == null) throw new ArgumentNullException(nameof(dimension));
            base.Add(dimension);
            // 添加对象时订阅其内部变更事件
            dimension.DimensionChange += Dimensions_DimensionChange;
            OnAdded(new xEventArgs<Dimension>(dimension));
            OnChange(new xEventArgs<Dimension>(dimension)); 
        }

        public new bool Remove(Dimension dimension)
        {
            if (dimension == null) throw new ArgumentNullException(nameof(dimension));
            var result = base.Remove(dimension);
            if (result)
            {
                // 移除对象时取消订阅,避免内存泄漏
                dimension.DimensionChange -= Dimensions_DimensionChange;
                OnRemoved(new xEventArgs<Dimension>(dimension));
                OnChange(new xEventArgs<Dimension>(dimension));
            }
            return result;
        }

        // 补充Clear方法的实现,清空集合时批量取消所有元素的事件订阅
        public new void Clear()
        {
            foreach (var item in this)
            {
                item.DimensionChange -= Dimensions_DimensionChange;
            }
            base.Clear();
        }

        #region Event On Method
        protected virtual void OnAdded(xEventArgs<Dimension> e)
        {
            DimensionAdded?.Invoke(this, e);
        }
        protected virtual void OnRemoved(xEventArgs<Dimension> e)
        {
            // 修复触发错误委托的问题
            DimensionRemoved?.Invoke(this, e);
        }
        protected virtual void OnChange(xEventArgs<Dimension> e)
        {
            DimensionChange?.Invoke(this, e);
        }
        #endregion
    }
}
功能验证说明

修改完成后可实现三类变更的统一监听:

  • 新增Dimension对象时触发DimensionAdded和DimensionChange事件
  • 移除Dimension对象时触发DimensionRemoved和DimensionChange事件
  • 已添加的Dimension对象内部Id/Size属性修改时触发DimensionChange事件

内容的提问来源于stack exchange,提问作者Burak Çelebi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:09:05