Deep C# - Passing Parameters
Written by Mike James   
Thursday, 19 November 2015
Article Index
Deep C# - Passing Parameters
Pass by reference
Boxing
Making Clones

Passing parameters is easy as it always works in the same way, but the effects aren't always the same. It can be confusing and even error prone unless you understand how it all works. So does C# pass by value or reference?

This is Chapter 2 of our ebook on C# - a work in progress.

Deep C#

 Buy Now From Amazon

DeepCsharp360

 Chapter List

  1. Why C#?
    I Strong Typing & Type Safety
  2. Strong Typing
       Extract 
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
       Extract
    Structs & Classes 
  6. Inheritance
      
    Extract
    Inheritance
  7. Interfaces & Multiple Inheritance
      
    Extract Interface
  8. Controlling Inheritance
    II Casting & Generics
  9. Casting - The Escape From Strong Typing
      
    Extract Casting I
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic
    Typing
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures
    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For ***NEW!
    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions
    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material

 <ASIN:1871962714>

 <ASIN:B09FTLPTP9>

Passing Parameters

The difference between a value and a reference type can be dangerous when passing parameters to a method. Exactly what is passed and how it behaves confuses even experienced programmers who ask questions along the lines of - is this pass by value or pass by reference or pass by ... 

The rule is very simple, by default value types are passed by value and reference types are also passed by value!

That is by default C# always uses pass by value. 

However when you pass a reference variable by value it look a lot like passing by reference. This sounds complicated but as long as you keep the idea of a value and a reference clear its not so difficult.

Pass Value By Value

Consider first passing a value type by value.

We have the usual PointV struct (see Chapter One) and a method that simply sets one of its fields to a value:

public struct PointV
{
 public int x;
 public int y;
}

void MyMethod(PointV a)
{
 a.x = 10;
}

Notice that the method has nothing to do with the struct - it is part of some other object.

Next we create an instance of the struct using new to make sure its fields have been initialised:

PointV b=new PointV();
b.x = 5;

This results in a value variable b with it’s x field set to 5 as shown

 

fig1

 

If we now call MyMethod with b as parameter:

MyMethod(b);

a new local variable a is created and initially set to the same value as b, then a.x is set to 10.

The result is a local variable with its x field set to 10 as shown

 

fig2

 

Finally MyMethod terminates and all local variables are destroyed leaving only b with its values unchanged by the call as shown below.

 

fig3

 

Thus a call by value does not change the value of b the parameter passed into the method.

Pass Reference By Value

Now consider the reference type version of the same code i.e. what happens when you pass a reference type by value.

In this case we need the class version of the point type, i.e. a reference type version of the object, and a suitably modified MyMethod:

class PointR
{
 public int x;
 public int y;
}

void MyMethod(PointR a)
{
 a.x = 10;
}

As before we create an instance and set its x field to 5:

PointR b=new PointR();
b.x = 5;

fig4

 

This might look the same but as the diagram shows the situation is very different. Now we have a reference variable called b and its content is a reference to a PointR object created on the heap.

Now when we call MyMethod in exactly the same way,

MyMethod(b);

b is passed by value which means that a new local variable a is created and the contents of b are copied to it.

The big difference is now that the content of b is a reference to an object on the heap. The result is that we now have two reference variable referencing the object on the stack and when the assignment a.x=10 occurs in the method the object on the heap is changed as shown.

 

fig5

 

Once again when MyMethod terminates the behaviour is exactly the same. The local variables including a are destroyed but now the change made to the object on the heap persists as shown below.

fig6

 

You should now be able to appreciate that while both value and reference variables are passed by value the effect of making changes in the method are very different.

Also notice that in both cases you cannot make a change to the value of the paramter passed. In the value case this means you cannot change the data and in the reference case you cannot change what is referenced. That is in both cases assignment to a in the method  has no effect on the variable b passed into the method. 

 

Banner

 

To summarise: by default parameters are always passed by value and assignment has no effect on the variables passed in. Passing a reference type allows the method to change the fields of the object referenced. 



Last Updated ( Thursday, 19 November 2015 )