25

As I understand it, C# passes parameters into methods by reference. In VB.NET, you can specify this with ByVal and ByRef. The default is ByVal.

Is this for compatibility with Visual Basic 6.0, or is it just random? Also, how can I specify what to use in C#? I kind of like the idea of passing parameters by value.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jouke van der Maas
  • 4,117
  • 2
  • 28
  • 35
  • 3
    See http://pobox.com/~skeet/csharp/parameters.html for details of the defaults etc. – Jon Skeet Jun 14 '10 at 20:11
  • 3
    Good answer, Jon, but you're also an AI! – Steven Sudit Jun 14 '10 at 21:37
  • 4
    In vb6, parameters were passed as `ByRef` in the absence of the `ByVal` keyword. In .net languages, the default is by value. To facilitate migration and avoid confusion, vb.net requires that parameters be explicitly marked either `ByRef` or `ByVal`, but the VS editor will "auto-correct" parameters without such marking by adding "ByVal". Because there was never any C#-ish language which had pass-by-ref as the default behavior, there is no problem simply saying that unmarked parameters are pass-by-value. – supercat Oct 05 '12 at 19:15
  • Thanks @supercat for the history/context. I always wondered why I had to explicitly state `ByVal` when that's what I meant 99% of the time. Always thought it was kind of silly - knowing _the why_ makes it feel slightly less silly ;) – Jeff B Jan 22 '15 at 14:54
  • 1
    @JeffBridgman: I find it somewhat ironic that while the default-byref behavior of parameter passing in VB/QBasic has long been recognized as a mistake, closures in both VB6 and C# are done by reference "by default" [the only way to specify by-value is to create new variables for use by the closures]. Java only allows by-value, and requires closed-over variables to be declared `final`; my preference would be to require that closed-over variables either be marked `readonly` [equivalent to `final`] or else explicitly declared as being capturable-by-reference, but I didn't design the languages. – supercat Jan 22 '15 at 16:02

3 Answers3

59

Parameters in C# are, by default passed by value. There is no modifier to make this explicit, but if you add ref / out the parameter is by-reference.

The usual confusion here is the difference between:

  • passing a value-type by value (changes to the value-type are not visible to the caller, but value-types should ideally be immutable anyway)
  • passing a value-type by reference (changes to the value-type are visible to the caller, but value-types should ideally be immutable anyway - so important I'll say it twice ;p)
  • passing a reference by value (changes to fields/properties of the ref-type are visible to the caller, but reassigning the ref-type to a new/different object is not visible)
  • passing a reference by reference (changes to fields/properties, and reassigning the reference are visible to the caller)
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
13

Passing by value is the default in C#. However, if the variable being passed is of reference type, then you are passing the reference by value. This is perhaps the origin of your confusion.

Basically, if you pass a reference by value, then you can change the object it refers to and these changes will persist outside the method, but you can't make variable refer to a different object and have that change persist outside the method.

Tim Goodman
  • 23,308
  • 7
  • 64
  • 83
  • Marc Gravell edited basically this same info into his answer while I was typing this, making this answer kind of redundant I guess. – Tim Goodman Jun 14 '10 at 20:13
  • 3
    Your answer still has some value, since it directly addresses the distinction between modifying the reference and modifying the instance. Besides, it's best not to compare yourself to the "people" with 50+k rankings: I have it on good authority that Reed is an AI run by Google, and most of the others are likewise non-human. :-) – Steven Sudit Jun 14 '10 at 21:37
7

Parameters in C# are passed "ByVal" by default. You have to specify "ref" or "out" if you want different behavior.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373