.Net Basics – Parameter Referencing

By | February 22, 2016

As a developer who thinks in C# but who works with VB from time to time, I tend not define if a parameter is ByRef or ByVal unless I have to.

I have also at times needed to describe why an application wasn?t breaking when I was assigning a value to an object?s property in a called function and that value was needed in the calling method, when the parameter did not have the keyword ByRef in the method signature.

The reason behind this is a fundamental part of .Net (and any developer who uses C# or VB should be aware of):

In .Net primitive types such as int, string, Boolean and a number of others are passed into a method by the value, while non-primitive types are passed in by their reference.

Look at the code below. After calling method1 only the car object?s values have been change because by default non-primitive types are passed by their reference, while the values of the int and the string have not been updated because only the values were passed into method.

For parameters which are passed in as values .Net Common Language Runtime (CLR) creates new variables for them within the scope of the method, once a method has finished the variables gets cleaned up and are lost.

After method2 the values of the int and the string were updated because the parameters were being passed in via their reference, hence in the VB code the keyword ?ByRef? and in C# ?ref?. The CLR will update the object which is being referenced, in this case the variables which are in the Main method scope.

VB Code

Sub Main

	Dim doorNumber As Integer = 88
	Dim name As String = "Daniel"
	Dim car = New Car()
	car.Make = "Volkswagon"
	car.Model = "Polo"
	car.Year = 2016


	Console.WriteLine("--- Call Method1 ---")
	Method1(doorNumber, name, car)
	Console.WriteLine(doorNumber)' 88
	Console.WriteLine(name)' Daniel
	Console.WriteLine(car.ToString())' Make Volkswagon, Model Golf, Year 2016
	Console.WriteLine("--- Call Method2 ---")
	Method2(doorNumber, name, car)
	Console.WriteLine(doorNumber)' 8
	Console.WriteLine(name)' Michael
	Console.WriteLine(car.ToString())' Make Volkswagon, Model Golf, Year 2016
End Sub

Private Sub Method1(doorNumber As Integer, name As String, car As Car)
	doorNumber = 8
	name = "Michael"
	car.Model = "Golf"
End Sub
Private Sub Method2(ByRef doorNumber As Integer, ByRef name As String, car As Car)
	doorNumber = 8
	name = "Michael"
	car.Model = "Golf"
End Sub

Public Class Car
	Public Property Make() As String
	Public Property Model() As String
	Public Property Year() As Integer
	Public Overrides Function ToString() As String
		Return String.Format("Make {0}, Model {1}, Year {2}", Make, Model, Year)
	End Function
End Class

C#

void Main()
{
	int doorNumber = 88;
	string name = "Daniel";
	var car = new Car()
	{
		Make = "Volkswagon",
		Model = "Polo",
		Year = 2016
	};

	Console.WriteLine("--- Call Method1 ---");
	Method1(doorNumber, name, car);
	Console.WriteLine(doorNumber); // 88
	Console.WriteLine(name); // Daniel
	Console.WriteLine(car.ToString()); // Make Volkswagon, Model Golf, Year 2016
	Console.WriteLine("--- Call Method2 ---");
	Method2(ref doorNumber,ref name, car);
	Console.WriteLine(doorNumber); // 8
	Console.WriteLine(name); // Michael
	Console.WriteLine(car.ToString()); // Make Volkswagon, Model Golf, Year 2016
}

void Method1(int doorNumber, string name, Car car)
{
	doorNumber = 8;
	name = "Michael";
	car.Model = "Golf";
}
void Method2(ref int doorNumber, ref string name, Car car)
{
	doorNumber = 8;
	name = "Michael";
	car.Model = "Golf";
}
public class Car
{
	public string Make { get; set; }
	public string Model { get; set; }
	public int Year { get; set; }
	public override string ToString()
	{
		return string.Format("Make {0}, Model {1}, Year {2}", Make,Model,Year);
	}
}

// Define other methods and classes here

Leave a Reply