Are event arguments passed by reference or value in C#?

我的未来我决定 提交于 2019-12-03 23:43:58

I know that some values are passed via value (like int and long), and others are passed by reference (like Strings) when you pass them to functions.

Nope. By default everything is passed by value - but when you're using reference types, the "everything" is a reference. That reference is passed by value. That's not the same as pass by reference. See my article on parameter passing for more details.

Event arguments are exactly the same - any references are passed by value, assuming the corresponding delegate doesn't use out or ref parameters.

EDIT: So to address your concern: yes, if your event argument is mutable and you're going to act on a different thread, you should create a copy first... or alternatively, pass the existing reference and then create a new (empty) list in your worker thread.

Arguments themselves are passed by value by default. However, depending on their type, they can be values or references to the actual values you're working with.

Note that this is not the same as what is commonly known as passing by reference, as the very value actually passed to an argument is copied (i.e. passed by value). However, the effect is similar in that if you change the referenced object within the method, the changes will be visible outside of the method (in the code where you invoked the method), too.

Now, when passing by value, there is nothing special about event arguments; whether the values are copied or only their references entirely depends on their type. So, as you said, int and long arguments (and some more, any struct types) are value types, while others like string (and any class instances) are reference types.

Note that a true passing by reference is possible in C#, too, but that requires the ref keyword.

In the standard event pattern there are two references passed in:

 void FormClosing(object sender, FormClosingEventArgs e) { ... }

those two references are passed 'by value', using for example sender = null will have no effect outside the handling method.

But you can easily pass a value back:

void FormClosing(object sender, FormClosingEventArgs e)
{
    ...
    e.Cancel = true;  // this will pass back to the caller
}

The event arguments are passed according to the type of the arguments and the signature of the event handler's delegate (in, out or ref) - if it is a class, then a copy of the reference is passed, if it is a struct, then the copy of the value is passed (assuming signature does not specify out or ref).

The event arguments are usually a class (usually inherits from EventArgs) and are often used to return values such as eventArgs.DoCancel to the caller.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!