使用EventArgs将信息传递回调用类

r_a*_*kog 25 c#

为了将信息传递回调用事件的类,修改事件处理程序中的EventArgs是不受欢迎的?

例如,如果我有一个低级别的通信类需要验证SSL的证书,但它无法知道有效的证书是什么样的,因为这是该类的不同用户的知识.

class ValidationEventArgs : System.EventArgs
{
    public X509Certificate Certificate { get; set; }
    public bool Valid { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后在使用对象中,它们连接到事件,并以某种方式检查它以更改Valid标志以指示证书是否可接受.

comms.ValidationEvent += CertValidationHandler;

void CertValidationHandler(ValidationEventArgs args)
{
    if (args.Certificate.Issuer.Contains(COMPANY_NAME)
        args.Valid = true;
}
Run Code Online (Sandbox Code Playgroud)

我发现像这样使用的EventArgs的引用,但我也看到人们说它不推荐.

编辑:也许我应该澄清这不是继承EventArgs,而是将它们用作双向沟通渠道.正如其他人所评论的那样,这是可以接受的,谷歌采取相反的任何噪音可能只是人们误解/误用了这个概念,现在却有同样的个人运动反对goto.

Tre*_*ley 43

问自己以下问题,"当我发布一个事件时,我是否希望任何订阅者更改任何EventArgs值"?如果答案是否定的,例如,您正在广播只读信息,那么使该类不可变,但是如果您需要来自订阅者的一些反馈,则使需要更改的属性变为可变.

为了澄清,在一个广播示例中,我们想告诉任何订户一些东西,但不要让他们改变价值.

public class ProgressEventArgs : EventArgs
{
    public ProgressEventArgs(int current)
    {
        this.Current = current;
    }

    public int Current { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

同样,我们也可以提出一个事件来询问班级本身不知道的信息.

public class FeedbackEventArgs : EventArgs
{
    public bool ShouldContinue { get; set; }
    public string Reason { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是旧的,但我想指出一个人在使用这种方法时应该小心,因为每个事件可能有多个用户,但是传递相同的事件对象因此使用简单的setter可能会导致数据被覆盖. (2认同)

jup*_*upi 8

您可以通过Generic Types方法使用EventArgs类.在此示例中,我将使用Rect类作为返回类型:

public EventHandler<Rect> SizeRectChanged;
Run Code Online (Sandbox Code Playgroud)

举办活动:

if(SizeRectChanged != null){
   Rect r = new Rect(0,0,0,0);
   SizeRectChanged(this,r);
}
Run Code Online (Sandbox Code Playgroud)

听取活动:

anyElement.SizeRectChanged += OnSizeRectChanged;

public void OnSizeRectChanged(object sender, Rect e){
    //TODO abything using the Rect class
    e.Left = e.Top = e.Width = e.Height = 50;
}
Run Code Online (Sandbox Code Playgroud)

  • 继承EventArgs的约束已在.net 4.5中删除. (4认同)