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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1530867/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:28:52  来源:igfitidea点击:

Understanding C# Events use of sender object

c#eventspass-by-reference

提问by Adam Cobb

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...

问题是我的大脑仍然在我认为的指针模式下工作......

采纳答案by Geoff

I don't know that I entirely understand your question. But to answer you in part:

我不知道我完全理解你的问题。但要部分回答你:

You would get a reference to your object.

您将获得对您的对象的引用。

回答by Julien Lebosquain

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 Buttonin a Clickevent on a button). If you want to pass arbitrary data in a custom event, inherits from EventArgs and pass it as the second argument.

关于事件,发送者参数总是生成事件(例如,该对象Button在一个Click事件上的按钮)。如果要在自定义事件中传递任意数据,请从 EventArgs 继承并将其作为第二个参数传递。

回答by MusiGenesis

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 objectwasn't passed by reference, textBox1would retain whatever text you typed into it.

如果object不是通过引用传递,textBox1将保留您输入的任何文本。

回答by Karthik

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;                        
    }
}

回答by Akira K.

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)

为每个控件访问它,无论控件类型如何(上面只是硬写的,它必须是什么对象)