简体   繁体   English

了解 C# 事件对发送者对象的使用

[英]Understanding C# Events use of sender object

I am reasonably new to C# as a language (coming from a C++ background) and I am currently in the process of writing an application that makes use of an event driven API.我对 C# 作为一种语言(来自 C++ 背景)相当陌生,我目前正在编写一个使用事件驱动 API 的应用程序。

Primarily this consists of registering event/response handlers and starting event monitors then dealing with these asychronous events/responses.这主要包括注册事件/响应处理程序和启动事件监视器,然后处理这些异步事件/响应。

The thing i'm having a bit of trouble understanding is the use of the sender object.我有点难以理解的是发送者对象的使用。

What I would like to use it for is to pass a handle to a class object I have with various structures and data in when making a request (or setting up a monitor).我想使用它的目的是在发出请求(或设置监视器)时将句柄传递给我拥有的具有各种结构和数据的类对象。 And then on the response being recieved/the event being raised I can take the sender object, cast it back to the expected class type and access members, make further changes etc. so treating it as if it's just still a pointer to the original data (which I'm hoping it would be?).然后在收到响应/引发事件时,我可以获取发送者对象,将其转换回预期的类类型并访问成员,进行进一步更改等,因此将其视为仍然是指向原始数据的指针(我希望会是这样吗?)。

So my question really is, as I am passing a class object in my request, will this be effectively a reference, or will it be copied somewhere along the line by value as it is actually just a generic object and I will end up with an empty copy of my class object on the event?所以我的问题真的是,当我在请求中传递一个类对象时,这将是一个有效的引用,还是将它按值复制到某处,因为它实际上只是一个通用对象,我最终会得到一个事件中我的类对象的空副本?

Or the third option that i'm maybe completely on the wrong track here and should forget the whole thing?或者第三个选项,我可能完全走错了路,应该忘记整件事? :) :)

Problem is my brains still working in pointers mode I think...问题是我的大脑仍然在指针模式下工作,我认为......

It's a reference.这是一个参考。 Try out this code to see how it works:试试这段代码,看看它是如何工作的:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    Whatever(sender);
}

private void Whatever(object sender)
{
    TextBox tb = (TextBox)sender;
    tb.Text = "yo";
}

If object wasn't passed by reference, textBox1 would retain whatever text you typed into it.如果object不是通过引用传递的,则textBox1将保留您输入的任何文本。

I don't know that I entirely understand your question.我不知道我完全理解你的问题。 But to answer you in part:但要部分回答你:

You would get a reference to your object.您将获得对您的对象的引用。

In .NET, all classes are reference types, and a reference is always passed... by reference (the current implementation of a reference is a pointer that can be moved around by the GC when it needs to), so you don't have to worry about anything.在 .NET 中,所有类都是引用类型,并且总是通过引用传递引用(引用的当前实现是一个指针,可以在需要时由 GC 移动),所以你不需要必须担心任何事情。

About events, the sender parameter is always the object that generated the event (for example a Button in a Click event on a button).关于事件,sender 参数始终是生成事件的对象(例如Button上的Click事件中的 Button)。 If you want to pass arbitrary data in a custom event, inherits from EventArgs and pass it as the second argument.如果要在自定义事件中传递任意数据,请从 EventArgs 继承并将其作为第二个参数传递。

Just a note: If you have multiple different controls leading to the same method you can use请注意:如果您有多个不同的控件导致您可以使用相同的方法

((Control)sender)

to access it for every control, regardless the type of control (above it was just hardwritten, what object it has to be)为每个控件访问它,而不管控件的类型(上面只是硬写的,它必须是什么对象)

The good thing about using this technique is that is even applicable on other platforms such as MonoDevelop using mono.使用这种技术的好处是它甚至适用于其他平台,例如使用单声道的 MonoDevelop。 Example of this would be :这方面的例子是:

protected void GetDate(object sender, EventArgs e)
{
     Gtk.Calendar calendar = (Gtk.Calendar)sender;
     HomeLabel.Text = calendar.Date.ToString(); 
}

When parameters are passed by reference,当参数通过引用传递时,

1. The properties present inside the reference instance can be change without affecting the original reference instance. 1. 引用实例中存在的属性可以在不影响原始引用实例的情况下进行更改。

2. Original reference can be changed using the ref keyword. 2. 可以使用 ref 关键字更改原始引用。

The following is an example下面是一个例子

public partial class ParentForm : Form
{
    public ParentForm()
    {
        InitializeComponent();
        ChildForm childForm = new ChildForm();
        ChangeCaption( childForm );
        //Will display the dialog with the changed caption.
        childForm.ShowDialog();
        ChangeCaption( ref childForm );
        //Will give error as it is null
        childForm.ShowDialog();
    }

    void ChangeCaption( ChildForm formParam )
    {
        // This will change openForm’s display text
        formParam.Text = "From name has now been changed";
        // No effect on openForm
        formParam = null;                        
    }


    void ChangeCaption( ref ChildForm formParam )
    {
        // This will change openForm’s display text
        formParam.Text = "From name has now been changed";
        // This will destroy the openForm variable!
        formParam = null;                        
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM