C#中代表的实现

Ram*_*Ram 3 c# delegates

我正在尝试学习如何在C#中有效地使用委托,我只是想知道是否有人可以指导我...以下是使用委托的示例实现...我所做的只是通过委托传递值从一个班级到另一个班级......请告诉我这是否是正确的实施方式......还有你的建议......

此外,请注意我已取消注册代表:

void FrmSample_FormClosing(object sender, FormClosingEventArgs e)
{
     sampleObj.AssignValue -= new Sample.AssignValueDelegate(AssignValue);
}
Run Code Online (Sandbox Code Playgroud)

这是否需要取消注册?

以下是我写的代码..

public partial class FrmSample : Form
{
    Sample sampleObj;

    public FrmSample()
    {
        InitializeComponent();

        this.Load += new EventHandler(FrmSample_Load);
        this.FormClosing += new FormClosingEventHandler(FrmSample_FormClosing);

        sampleObj = new Sample();
        sampleObj.AssignValue = new Sample.AssignValueDelegate(AssignValue);            
    }

    void FrmSample_FormClosing(object sender, FormClosingEventArgs e)
    {
        sampleObj.AssignValue -= new Sample.AssignValueDelegate(AssignValue);
    }

    void FrmSample_Load(object sender, EventArgs e)
    {
        sampleObj.LoadValue();
    }

    void AssignValue(string value)
    {
        MessageBox.Show(value);
    }
}

class Sample
{
    public delegate void AssignValueDelegate(string value);
    public AssignValueDelegate AssignValue;

    internal void LoadValue()
    {
        if (AssignValue != null)
        {
            AssignValue("This is a test message");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请提供您对这是否正确的反馈...

谢谢,拉姆

Han*_*ant 6

当事件的参考保持包含委托目标活着的过长的对象明确注销事件处理程序才是必需的.在您的情况下,sampleObj将具有对Form对象的引用.C#语法糖隐藏了这一点,编译器实际生成了这段代码:

sampleObj.AssignValue =新Sample.AssignValueDelegate(,AssignValue);

如果参数初始化Delegate.Target属性,则AssignValue参数初始化Delegate.Method属性.

这意味着只要sampleObj对象保持引用,表单对象也会保持引用,并且不会被垃圾回收.但是,在您的情况下,唯一具有sampleObj引用的对象是表单对象本身.垃圾回收器没有像这样的循环引用的麻烦,并且会检测到没有对这两个对象的其他引用.并将同时收集它们.

这有一个(不常见的)例外,你会遇到问题,sampleObj类在窗体关闭生成事件.如果事件由表单之外的某些事件触发,例如某些硬件事件,则可能发生这种情况.该事件仍然可以在表单类中运行代码.您通常会很快注意到这一点,任何在表单中引用控件的尝试都会抛出ObjectDisposed异常.