Library tutorials & articles
Parameter Passing in C#
- Preamble
- Value Parameters
- Reference Parameters
- Output Parameters & Parameter Arrays
Reference Parameters
Reference parameters don't pass the values of the variables used in the function member invocation
- they use the variables themselves. Rather than creating a new storage location for the
variable in the function member declaration, the same storage location is used, so the value of
the variable in the function member and the value of the reference parameter will always be the
same. Reference parameters need the ref modifier as part of both the
declaration and the invocation - that means it's always clear when you're passing something
by reference. Let's look at our previous examples, just changing the parameter to
be a reference parameter:
void Foo (ref StringBuilder x)
{
x = null;
}
...
StringBuilder y = new StringBuilder();
y.Append ("hello");
Foo (ref y);
Console.WriteLine (y==null);
Output:
Here, because a reference to y is passed rather than its value, changes to
the value of parameter x are immediately reflected in y. In
the above example, y ends up being null. Compare this with
the result of the same code without the ref modifiers.
Now consider the struct code we had earlier, but using reference parameters:
void Foo (ref IntHolder x)
{
x.i=10;
}
...
IntHolder y = new IntHolder();
y.i=5;
Foo (ref y);
Console.WriteLine (y.i);
Output:
The two variables are sharing a storage location, so changes to x are
also visible through y, so y.i has the value 10 at the
end of this code.
Sidenote: what is the difference between passing a value object by reference and a reference object by value?
You may have noticed that the last example, passing a struct by reference, had the same effect in this code as passing a class by value. This doesn't mean that they're the same thing, however. Consider the following code:
void Foo (??? IntHolder x)
{
x = new IntHolder();
}
...
IntHolder y = new IntHolder();
y.i=5;
Foo (??? y);
In the case where IntHolder is a struct (i.e. a value type) and the
parameter is a reference parameter (i.e. replace ??? with ref above),
y ends up being a new IntHolder value - i.e. y.i is 0.
In the case where IntHolder is a class (i.e. a reference
type) and the parameter is a value parameter (i.e. remove ??? above), the value
of y isn't changed - it's a reference to the same object it was before the function member
call. This difference is absolutely crucial to understanding parameter passing in C#,
and is why I believe it is highly confusing to say that objects are passed by reference by default
instead of the correct statement that object references are passed by value by default.
Related articles
Related discussion
-
Query Tool to Excel using C# and .NET
by BarbaMariolino (1 replies)
-
looking for help on asp
by cladironbeard (2 replies)
-
Socket Programming in C# - Part 1
by graumanoz (23 replies)
-
LINQ in Action
by naser1 (0 replies)
-
Creating a Windows Service in VB.NET
by Templario55 (107 replies)
Related podcasts
-
Object-Oriented Programming in Ruby
In this episode, I talk with Scott Bellware about object-oriented programming in Ruby, and Ruby's object model. This is taken from a private conversation, and the audio quality suffers at times. Much thanks to Scott for allowing this to be released.This episode of the Alt.NET Podcast is bro...
Events coming up
-
Aug
28
St. Louis Day of .NET
St. Charles, United States
Technical conference with be 2 full days of content with over 40 sessions from local and national speakers, with topics such as:•.NET languages: C#, VB.NET•Technologies: WPF, Silverlight, WCF•Development tools: Visual Studio, TFS, Expression Blend
So how do I pass a reference type by value - e.g. prevent changes/side effects to that instance? Can this be done at all?
Thanks
Nice layout. Easy to read and understand. Well done.
This thread is for discussions of Parameter Passing in C#.