C# 使用 EventArgs 将信息传递回调用类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9307627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using EventArgs to pass information back to invoking class
提问by r_ahlskog
It is frowned upon to modify EventArgs in event handlers for the purpose of passing information back to the class invoking the event?
为了将信息传递回调用事件的类而修改事件处理程序中的 EventArgs 是不受欢迎的?
For instance if I have a low-level communication class needing to validate a certificate for SSL but it has no way of knowing what a valid certificate looks like since that is the knowledge of the different users of the class.
例如,如果我有一个需要验证 SSL 证书的低级通信类,但它无法知道有效证书的样子,因为这是该类不同用户的知识。
class ValidationEventArgs : System.EventArgs
{
public X509Certificate Certificate { get; set; }
public bool Valid { get; set; }
}
Then in the using objects they hook up to the event, and check it somehow changing the Validflag to indicate if the certificate is acceptable or not.
然后在使用对象中,它们连接到事件,并检查它以某种方式更改Valid标志以指示证书是否可接受。
comms.ValidationEvent += CertValidationHandler;
void CertValidationHandler(ValidationEventArgs args)
{
if (args.Certificate.Issuer.Contains(COMPANY_NAME)
args.Valid = true;
}
I have found referencesof EventArgs being used like this but I have also seen people saying it is not recommended.
我发现像这样使用 EventArgs 的引用,但我也看到有人说不推荐这样做。
Edit:Maybe I should clarify that this is not about inheriting EventArgs, but using them as a bi-directional channel of communication. As others commented this is acceptable and whatever noise Google picks up to the opposite is probably just people having misunderstood/misused the concept and now has the same personal crusade against as goto.
编辑:也许我应该澄清一下,这不是关于继承 EventArgs,而是将它们用作双向通信渠道。正如其他人评论的那样,这是可以接受的,无论 Google 收到什么反对意见,都可能只是人们误解/误用了这个概念,现在对goto.
采纳答案by Trevor Pilley
Ask yourself the following question, "when I publish an event, do I want any subscriber to alter any of the EventArgs values"? If the answer is no, e.g. you are broadcasting readonly information then make the class immutable, however if you need some feedback from a subscriber then make the properties which need to be altered mutable.
问自己以下问题,“当我发布事件时,我是否希望任何订阅者更改任何 EventArgs 值”?如果答案是否定的,例如您正在广播只读信息,则使该类不可变,但是,如果您需要来自订阅者的一些反馈,则使需要更改的属性可变。
To clarify, in a broadcast example, we want to tell any subscriber something but not let them alter the value.
澄清一下,在广播示例中,我们想告诉任何订阅者一些事情,但不让他们改变值。
public class ProgressEventArgs : EventArgs
{
public ProgressEventArgs(int current)
{
this.Current = current;
}
public int Current { get; private set; }
}
Equally though, we could also raise an event to ask for information the class itself does not know.
同样,我们也可以引发一个事件来询问类本身不知道的信息。
public class FeedbackEventArgs : EventArgs
{
public bool ShouldContinue { get; set; }
public string Reason { get; set; }
}
回答by Christian Hayter
I'm not aware of any recommendation against inheriting from EventArgs; as far as I know, inheriting from it is good practice.
我不知道有任何反对从 继承的建议EventArgs;据我所知,继承它是一种很好的做法。
As a general principle, I suggest that you make your derived classes immutable. That will make it much safer to pass between threads should you need to do so. The simplest way to do this is to declare your properties as { get; private set; }, and only set them in the constructor. Obviously you can't do that with the specific use case you have in the question, but you should do it where possible.
作为一般原则,我建议您使派生类不可变。如果您需要这样做,这将使在线程之间传递更安全。最简单的方法是将您的属性声明为{ get; private set; },并且只在构造函数中设置它们。显然,对于问题中的特定用例,您不能这样做,但您应该尽可能这样做。
回答by jupi
You can use the EventArgs class through the Generic Types approach. In this sample, i will use the Rect class with as return type:
您可以通过通用类型方法使用 EventArgs 类。在此示例中,我将使用 Rect 类作为返回类型:
public EventHandler<Rect> SizeRectChanged;
Raising the event:
引发事件:
if(SizeRectChanged != null){
Rect r = new Rect(0,0,0,0);
SizeRectChanged(this,r);
}
Listening the event:
监听事件:
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;
}

