Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 事件触发事件_C#_Events_.net 4.0 - Fatal编程技术网

C# 事件触发事件

C# 事件触发事件,c#,events,.net-4.0,C#,Events,.net 4.0,我有一个对象在我的类中是私有的。如果该对象触发一个事件,我希望将该事件传递给使用我的类的任何对象。目前我是这样做的,我在构造函数中加入了: cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args)); 有没有更好的方法来做到这一点,是否有任何类似于类不会被释放的问题,因为它本身有一个事件,我需要在dispose函数中手动取消订阅 将发送器从激发对象更改为此是可选的 测试代码的完整版本 using Sy

我有一个对象在我的类中是私有的。如果该对象触发一个事件,我希望将该事件传递给使用我的类的任何对象。目前我是这样做的,我在构造函数中加入了:

cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args));
有没有更好的方法来做到这一点,是否有任何类似于类不会被释放的问题,因为它本身有一个事件,我需要在dispose函数中手动取消订阅

将发送器从激发对象更改为
是可选的

测试代码的完整版本

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace placeholder
{
    internal class FilterBase : UserControl, IFilterObject
    {
        public FilterBase(string name)
        {
            InitializeComponent();
            cbName.CheckedChanged += ((sender, args) => this.CheckChanged(this,args));
            cbName.Name = name;
            this.Name = name;
        }

        private CheckBox cbName;
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.cbName = new System.Windows.Forms.CheckBox();
            this.SuspendLayout();
            // 
            // cbName
            // 
            this.cbName.AutoSize = true;
            this.cbName.Location = new System.Drawing.Point(4, 4);
            this.cbName.Name = "cbName";
            this.cbName.Size = new System.Drawing.Size(79, 17);
            this.cbName.TabIndex = 0;
            this.cbName.Text = "Filter Name";
            this.cbName.UseVisualStyleBackColor = true;
            // 
            // UserControl1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.AutoSize = true;
            this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
            this.Controls.Add(this.cbName);
            this.Name = "Filter Name";
            this.Size = new System.Drawing.Size(86, 24);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        public event EventHandler CheckChanged;
        public bool Checked
        {
            get { return cbName.Checked; }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统图;
使用系统数据;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间占位符
{
内部类FilterBase:UserControl、IFilterObject
{
公共过滤器数据库(字符串名称)
{
初始化组件();
cbName.CheckedChanged+=((发送方,参数)=>this.CheckedChanged(this,参数));
cbName.Name=Name;
this.Name=Name;
}
私人姓名;
///  
///必需的设计器变量。
/// 
private System.ComponentModel.IContainer components=null;
///  
///清理所有正在使用的资源。
/// 
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域组件设计器生成的代码
///  
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
/// 
私有void InitializeComponent()
{
this.cbName=new System.Windows.Forms.CheckBox();
这个.SuspendLayout();
// 
//cbName
// 
this.cbName.AutoSize=true;
this.cbName.Location=新系统.图纸.点(4,4);
this.cbName.Name=“cbName”;
this.cbName.Size=新系统.Drawing.Size(79,17);
this.cbName.TabIndex=0;
this.cbName.Text=“过滤器名称”;
this.cbName.UseVisualStyleBackColor=true;
// 
//用户控制1
// 
此.AutoScaleDimensions=新系统.Drawing.SizeF(6F,13F);
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize=true;
this.AutoSizeMode=System.Windows.Forms.AutoSizeMode.growtandshrink;
this.Controls.Add(this.cbName);
this.Name=“过滤器名称”;
该尺寸=新系统图纸尺寸(86,24);
此选项为.resume布局(false);
这个。执行布局();
}
#端区
公共事件事件处理程序已更改;
公共图书馆检查
{
获取{return cbName.Checked;}
}
}
}

好吧,这将防止当前对象在
cbName
处于活动状态时被垃圾收集,但听起来这不太可能是个问题。。。这是一个固有的事实,即无论您做什么,您都有一个对
this
的引用(因为您想要启动这个对象的CheckChanged处理程序)

这样做的一个缺点是,即使您想取消订阅,也无法取消订阅(例如,在Dispose方法中)。另一种方法是使用实际方法:

private void CbNameCheckedChangedHandler(object sender, EventArgs e)
{
    CheckedChanged(this, args);
}

...
cbName.CheckedChanged += CbNameCheckedChangedHandler;

// If you ever want to remove the handler
cbName.CheckedChanged -= CbNameCheckedChangedHandler;
请注意,这都是假设您的
CheckedChanged
事件是空安全的,例如,它声明为:

public event EventHandler CheckedChanged = delegate {};

否则,如果没有人订阅该事件,则当触发
cbName.CheckedChanged
时,您将得到一个
NullReferenceException

事件实际上类似于自动属性。您可以定义自己的
add
remove
方法,将委托直接传递给子控件,从而删除额外的间接级别:

public event EventHandler CheckChanged {
    add { cbName.CheckChanged += value; }
    remove { cbName.CheckChanged -= value; }
}

这将删除存储在类中的额外
委托
(因为在标准事件的后台使用了
委托
字段)

感谢空引用警告!很酷,我不知道。有没有什么方法可以让我的蛋糕和吃它也改变发件人从cbName到FilterBase使用类似的东西?像往常一样,Jon Skeet在这里有一篇关于事件工作原理的伟大文章:。如果线程安全适用于您的情况,请务必了解线程安全。