Passing by Value vs Passing by Reference — RexDac Academy

RexDac AcademyTechnical notes · Some prior knowledge helps
0%Published notes read · this device

Level 3 — Functions

Passing by Value vs Passing by Reference

Original notes by SunDiaL · View English source

Part 2 of the confusing saga. Parameters are also split into two, combined with Value Types vs Reference Types, this makes for a total of 4 combinations.

Passing by value

This is the standard way pass parameters. The parameter variable is assigned a copy of the value.

  • For value types, this means the value itself is copied.
  • For reference types, this means the address of the object is copied. This is the same as passing by pointer in C++

Passing by reference

The other way to pass parameters.

  • In this case the object is used "directly". This is the same as passing by reference in C++, note however that references in C# are not exactly the same thing as references in C++.

    For a more in depth explanation regarding C++ references, see Pointer vs Reference

It's a weird thing to explain without seeing it in action so, and seeing it in action requires knowledge about classes so come back to these examples later.

Examples

1. Value type by value

void ByVal(int x)
{
	x++;
	Console.WriteLine(x);
}

void Main()
{
	int x = 1; 
	ByVal(x); // will print 2
	Console.WriteLine(x); //will print 1, because there are now two "1" objects sitting in memory. One for the x in main, and one for the x in ByVal.
}

2. Value type by reference

void ByRef(ref int x)
{
	x++;
	Console.WriteLine(x);
}

void Main()
{
	int x = 1; 
	ByVal(ref x); // will print 2
	Console.WriteLine(x); //will print 2, because x in ByRef uses the the object itself, not a copy.
}

3. Reference type by value

class Test
{
	public int val;
}
void ByValIncrement(Test x)
{
	x.val++
	Console.WriteLine(x.val);
}

void ByValIncrement(Test x)
{
	x = new Test();
	x.val = 3;
	Console.WriteLine(x.val);
}

void Main()
{
	Test x = new Test();
	x.val = 1;
	ByValIncrement(x); // will print 2
	Console.WriteLine(x.val); //will print 2, because the same address was used.
	
	ByValChange(x) //will print 3.
	Console.WriteLine(x.val); //will print 2, because the object was changed inside the function. 	
}

4. Reference type by reference

class Test
{
	public int val;
}
void ByValIncrement(ref Test x)
{
	x.val++
	Console.WriteLine(x.val);
}

void ByValIncrement(ref Test x)
{
	x = new Test();
	x.val = 3;
	Console.WriteLine(x.val);
}

void Main()
{
	Test x = new Test();
	x.val = 1;
	ByValIncrement(ref x); // will print 2
	Console.WriteLine(x.val); //will print 2, because the same object was used.
	
	ByValChange(ref x) //will print 3.
	Console.WriteLine(x.val); //will print 3, because the object was used "directly".
}