具有多个类的代理和事件

时间:2013-07-18 16:22:50

标签: c# events delegates

我花了不少时间来开发一个使用代理和事件在类之间进行通信的演示。我想知道这是否是在类之间完成数据传递的最佳实践方法。如果有更好的方法,请告诉我。具体来说,如果子类中发生了某些事情,您如何将其返回到主类。当通过将用户界面与业务逻辑级别和数据访问级别分离来进行n层架构时,这将特别有用。

我有一个包含3个文本框的表单:tb1,tb2和tbAnswer。 我还有一个显示“添加”的按钮,它只是按钮1。

主要形式是:

namespace DelegateTest
{
    public delegate void ShowMessage(object sender, Form1.AnswerEventArgs e);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void a_OnShowMessage(object sender, AnswerEventArgs e)
        {
            tbAnswer.Text = e.answer;
        }

        public class AnswerEventArgs :EventArgs
        {
            public string answer { get; set; }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AddClass a = new AddClass();
            a.OnShowMessage += new ShowMessage(a_OnShowMessage);
            a.AddMe(Convert.ToInt16(tb1.Text), Convert.ToInt16(tb2.Text));
        }
    }
}

,名为AddClass.cs的子表单是:

namespace DelegateTest
{
    class AddClass
    {
        public event ShowMessage OnShowMessage;
        public void AddMe(int a, int b)
        {
            Form1.AnswerEventArgs e = new Form1.AnswerEventArgs();
            e.answer = (a+b).ToString();
            OnShowMessage(this, e);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

除了两个细节外,你的方法是合理的。

首先,如果在添加任何处理程序之前引发事件,则会发生NullPointerException。你可以通过两种方式解决这个问题。

1)制作本地副本(以避免竞争条件)并将其检查为空:

var showMessage = OnShowMessage;
if (showMessage != null)
{
    showMessage(this, e);
}

2)将您的活动初始化为空委托:

public event ShowMessage OnShowMessage = delegate { };

其次,在这种情况下,您不需要声明自己的委托。您只需使用自己的事件参数创建标准EventHandler

public event EventHandler<Form1.AnswerEventArgs> OnShowMessage = delegate { };

有关详细信息,请参阅How to: Publish Events that Conform to .NET Framework Guidelines