c# - C#中委托(delegate)的实现

标签 c# delegates

我正在尝试学习如何在 C# 中有效地使用委托(delegate),我只是想知道是否有人可以指导我完成...以下是使用委托(delegate)的示例实现...我所做的只是传递一个值通过一个类(class)到另一个类(class)的委托(delegate)...请告诉我这是否是正确的实现方式...以及您的建议...

另外,请注意,我已经在 :

中注销了委托(delegate)人
void FrmSample_FormClosing(object sender, FormClosingEventArgs e)
{
     sampleObj.AssignValue -= new Sample.AssignValueDelegate(AssignValue);
}

是否需要注销?

下面是我写的代码..

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");
        }
    }
}

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

谢谢, 内存

最佳答案

仅当事件引用使包含委托(delegate)目标的对象保持事件时间过长时,才需要显式注销事件处理程序。在您的例子中,sampleObj 将引用 Form 对象。 C# 语法糖隐藏了这一点,编译器实际上生成了这段代码:

sampleObj.AssignValue = new Sample.AssignValueDelegate(this, AssignValue);

this 参数初始化 Delegate.Target 属性,AssignValue 参数初始化 Delegate.Method 属性。

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

对此有一个(不常见的)异常(exception),当表单关闭时 sampleObj 类会生成事件,您会遇到麻烦。如果事件是由表单之外的事物触发的,例如某些硬件事件,则可能会发生这种情况。该事件仍然可以在表单类中运行代码。您通常很快就会注意到这一点,任何在表单中引用控件的尝试都会引发 ObjectDisposed 异常。

关于c# - C#中委托(delegate)的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2652214/

相关文章:

c# - JSON 根节点 - 与类名称不同

c# - delegate 关键字与 lambda 表示法

ios - UIDocumentPickerViewController - 未调用委托(delegate)方法

ruby - cocoa /MacRuby : How to write a toolbar which accepts custom items?

objective-c - 进入背景时,iOS拍摄快照的确切时间?

C# 来自循环的匿名对象的匿名数组

c# - 方法签名中 List<T> 和 IEnumerable<T> 的区别

c# - 如何防止在 AddingNew 事件中将项目添加到 BindingList 中?

c# - LINQ 扩展委托(delegate)

c# - 修剪字符串并将其转换为小写的最快方法