Parameters

Parameters

Methods may have a number of parameters. Parameters define a set of arguments that must be provided to the method in order for it to operate as expected.

For example, a method that doubles an integer number will have the integer number as a parameter.


using System;

public class Program
{
	public static void Main()
	{
		Console.WriteLine(DoubleNumber(2));
	}

	public static int DoubleNumber(int input)
	{
	   return input * 2;
	}
}
                

Passing by Value

By default, parameters will be passed by value. Passing by value means that the value is only changed within the scope of the method as a copy of the value has been taken and assigned to the parameter.

using System;
public class Program
{
public static void Main()
{
int x = 2;
Console.WriteLine(x); //Outputs 2
DoubleNumber(x);
Console.WriteLine(x); //Still outputs 2
}
public static void DoubleNumber(int input)
{
 input = input * 2;
}
}

Passing a reference type by value results in a copy of the reference being made. Although the old reference and the reference within the method are not the same variables, they both point at the same object. As both variables point to the same object, any changes you make to the object will be reflected from either reference.

Reference vs value types

Passing By Reference

Alternatively, it is possible to pass to a method by reference. This requires the use of the ref modifier.

From our earlier example, we can see the impact passing by reference has on the DoubleNumber Function.

using System;
public class Program
{
public static void Main()
{
int x = 2;
Console.WriteLine(x); //Outputs 2
DoubleNumber(ref x);
Console.WriteLine(x); //Outputs 4
}
public static void DoubleNumber(ref int input)
{
 input = input * 2;
}
}

Passing our value as a reference type means that the variable is modified outside the scope of the method.

Out Modifier

The out modifier is similar to the ref modifier however, the variable does not need to be assigned before it is passed to the method and it must be assigned before execution comes out of the method.


using System;

public class Program
{
	public static void DoubleString(string inputWord, out string x, out string y)
	{
		x = $"{inputWord} >> {inputWord}";
		y = $"{inputWord} << {inputWord}";
	}

	public static void Main()
	{
		string a,b;
		DoubleString("Hello", out a, out b);
		Console.WriteLine(a);
		Console.WriteLine(b);
	}
}
                

Discards

It might not always be necessary to keep all of the variables when making a call to a method that uses out modifiers, we have the option to discard these values. To do this you can use an underscore in the position correlating to the value you wish to discard.


using System;

public class Program
{
	public static void DoubleString(string inputWord, out string x, out string y)
	{
		x = $"{inputWord} >> {inputWord}";
		y = $"{inputWord} << {inputWord}";
	}

	public static void Main()
	{
		string a;
		DoubleString("Hello", out a, out _);
		Console.WriteLine(a);
	}
}
                

If you name a variable “_” and attempt to use this in a method call – this will cause a compiler error.

Params Modifier

If you wish to pass an unknown number of parameters (of the same type) to a method, the params modifier can be used. This tells the method to accept any number of the same types as an array to be used within the method.


using System;

public class Program
{
	public static int SubtractElements(params int[] numbersToMultiply)
	{
		int total = 0;
		for(int i = 0; i < numbersToMultiply.Length; i++)
		{
			total = total - numbersToMultiply[i];
		}
		return total;
	}

	public static void Main()
	{
		int calc = SubtractElements(1,2,3,4);
		Console.WriteLine(calc);
	}
}
                

Optional Parameters

Methods can contain optional parameters that do not require passing as they can take on a pre-specified default value. To declare an optional parameter, it must be assigned to a value using ” = ” in its definition.

For Example:


using System;

public class Program
{
	public static void FavouriteInt(int fav = 42)
	{
         Console.WriteLine($"Your favourite number is {fav}");
	}

	public static void Main()
	{
		FavouriteInt();
		FavouriteInt(999);
	}
}
                

If a value is not present at the calling side when the code is sent for compilation, the compiler will actually add it to the call. In this case, the compiler will change FavouriteInt() to FavouriteInt(42).

Optional parameters cannot be marked with ref or out.

Mandatory parameters (those without a default) must occur before optional parameters in both the call and the method.

Named Arguments

It is not necessary to rely on matching positions to supply a method with arguments, instead, you can name the parameters.

You can do this at the calling side by putting the name of the target parameter, followed by a colon, followed by the value:


using System;

public class Program
{
	public static void IsAFactorOf(int target, int dividedBy)
	{
		if(target % dividedBy == 0)
		{
			Console.WriteLine($"Yes, {dividedBy} is a factor of {target}");
		} else {
			Console.WriteLine("No, Sorry");
		}
	}

	public static void Main()
	{
        IsAFactorOf(target: 10, dividedBy: 5);
		IsAFactorOf(target: 11, dividedBy: 2);
	}
}
                

You can mix positional and named arguments as long as the positional arguments come before the named ones.

Implicitly Typed Local Variables

In the majority of cases where you are declaring and initialising a variable at the same time, the compiler will be able to infer the type you wish to use. For example, the compiler can infer that “This is a string” is a string.

In these situations, it is possible to use the var keyword in place of the type keyword.


using System;

public class Program
{
	public static void Main()
	{
		string x = "This is a string";
		var y = "This is also a string";

		Console.WriteLine(x.GetType());
		Console.WriteLine(y.GetType());
	}
}
                

Once the compiler has inferred the type for the variable, it cannot be changed e.g. you cannot assign an int to a var that has already been inferred as a string.