为了将信息传递回调用该事件的类,修改事件处理程序中的EventArgs是不受欢迎的?
例如,如果我有一个低级别的通信类需要验证SSL的证书,但它无法知道有效的证书是什么样的,因为这是该类的不同用户的知识。
class ValidationEventArgs : System.EventArgs
{
public X509Certificate Certificate { get; set; }
public bool Valid { get; set; }
}
然后在使用对象中,它们连接到事件,并以某种方式检查它以更改Valid
标志以指示证书是否可接受。
comms.ValidationEvent += CertValidationHandler;
void CertValidationHandler(ValidationEventArgs args)
{
if (args.Certificate.Issuer.Contains(COMPANY_NAME)
args.Valid = true;
}
我发现像这样使用了references的EventArgs,但我也看到有人说不推荐这样做。
编辑:也许我应该澄清这不是关于继承EventArgs,而是将它们用作双向通信渠道。正如其他人所评论的那样,这是可以接受的,谷歌选择相反的任何噪音可能只是人们误解/误用了这个概念,现在和goto
有着相同的个人运动。
答案 0 :(得分:43)
问自己以下问题,“当我发布一个事件时,我是否希望任何订阅者更改任何EventArgs值”?如果答案是否定的,例如您正在广播只读信息,然后使该类不可变,但是如果您需要订阅者的一些反馈,那么需要更改的属性是可变的。
为了澄清,在一个广播示例中,我们想要告诉任何订户一些东西,但不要让他们改变价值。
public class ProgressEventArgs : EventArgs
{
public ProgressEventArgs(int current)
{
this.Current = current;
}
public int Current { get; private set; }
}
同样,我们也可以提出一个事件来询问该班级本身不知道的信息。
public class FeedbackEventArgs : EventArgs
{
public bool ShouldContinue { get; set; }
public string Reason { get; set; }
}
答案 1 :(得分:8)
您可以通过Generic Types方法使用EventArgs类。 在此示例中,我将使用带有返回类型的Rect类:
public EventHandler<Rect> SizeRectChanged;
举起活动:
if(SizeRectChanged != null){
Rect r = new Rect(0,0,0,0);
SizeRectChanged(this,r);
}
倾听活动:
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;
}
答案 2 :(得分:2)
我不知道有任何反对从EventArgs
继承的建议;据我所知,继承它是一种很好的做法。
作为一般原则,我建议您使派生类不可变。如果您需要这样做,那么在线程之间传递会更安全。最简单的方法是将属性声明为{ get; private set; }
,并仅在构造函数中设置它们。显然你不能用你在问题中的特定用例来做到这一点,但你应该尽可能这样做。