Named parameters were introduced in C# 4 and have become quite popular because of the benefits and usability they provide over positional parameters.
In this guide, we will learn the following:
To illustrate this, we will be creating a program to call a function which calculates the volume of common 3D shapes such as cubes, spheres, cylinders, pyramids, and cones using named parameters.
First, let's review couple of examples of positional parameters and analyze why the position of the function parameters matter.
Consider the below code, which calculates the volume of a cube when the length of the edge (side) is provided.
1double CalculateVolumeCube(double edge) {
2 return Math.Pow(edge,3);
3}
4
5double Volume = calculateVolumeCube(5);
6Console.WriteLine($"Volume: {Volume:N2}");
7// Answer is Volume: 125.00
Let's take another example of calculating a volume, but this time we are calculating the volume of a cylinder.
1double CalculateVolumeCylinder(double radius, double height) {
2 return Math.PI*Math.Pow(radius,2)*height;
3}
4
5double Volume = calculateVolumeCylinder(2,4);
6Console.WriteLine($"Volume: {Volume:N2}");
7// Answer is Volume: 50.27
The above function takes radius and height as the parameters and returns the volume of the cylinder. When we provide the radius as 2 and height as 4, we get the volume as 50.27 (rounded up to two decimals). These are called positional parameters as the order in which the arguments are provided matter.
For further perspective, review the code below :
1double CalculateVolumeCylinder(double height, double radius) {
2 return Math.PI*Math.Pow(radius,2)*height;
3}
4
5double Volume = calculateVolumeCylinder(2,4);
6Console.WriteLine($"Volume: {Volume:N2}");
What do you think the answer would be? Will it be the same as Volume: 50.27?
1// Answer is Volume: 100.53
You might not be expecting this answer, but by closely looking at the function definition, we can see that the first parameter is height and not radius.
Typically, programmers waste a lot of time debugging this type of code because it does not provide a run time or compile time exception. The above function contained only two parameters, but imagine a scenario where we have a function with four, five, or more parameters. In this case, you must ensure that you review the function definition carefully each time you are passing arguments.
Now we will make changes to the above code and call the same function with named parameters.
1double CalculateVolumeCylinder(double height, double radius) {
2 return Math.PI*Math.Pow(radius,2)*height;
3}
4
5double Volume = calculateVolumeCylinder(radius:2, height:4);
6Console.WriteLine($"Volume: {Volume:N2}");
7// Answer is Volume: 50.27
The above function calls give us the correct output, and there are two important things to consider:
Put simply, named parameters provide you the option to associate the arguments that you have passed through a function to the parameter names rather than its position in the parameter list.
1// Function definition
2void function(int param1, string param2, int param3) {}
3
4// Valid function calls
5function(12,param2:"Hello", 3);
6function(param3:45, param1:34, param2:"Hello");
7
8// Invalid function call
9function(param3:45, param1:34, "Hello");
Rule: You can use named parameters along with positional parameters, but they should be in order. Out-of-order named parameters are valid only if they are not followed by positional parameters .
Let's create a function that calculates the volume of the common 3D shapes and call it using named parameters.
1enum Shape {
2 Cone,
3 Cube,
4 Cylinder,
5 Pyramid,
6 Sphere
7 }
1double CalculateVolume(double length, double width, double height, double radius, double edge, Shape shapeType)
2 {
3 double volumeResult=0.0;
4
5 switch(shapeType) {
6 case Shape.Cone:
7 volumeResult = Math.PI*Math.Pow(radius,2)*(height/3);
8 break;
9 case Shape.Cube:
10 volumeResult = Math.Pow(edge,3);
11 break;
12 case Shape.Cylinder:
13 volumeResult = Math.PI*Math.Pow(radius,2)*height;
14 break;
15 case Shape.Pyramid:
16 volumeResult = length*width*(height/3);
17 break;
18 case Shape.Sphere:
19 volumeResult = 4*Math.PI*(Math.Pow(radius,3)/3);
20 break;
21 }
22 return volumeResult;
23
24 }
1// Calling the function by providing values through positional parameters.
2Volume = CalculateVolume(0, 0, 0, 0, 5, Shape.Cube);
3Console.WriteLine($"Volume: {Volume:N2}");
4// Answer is Volume: 125.00
5
6// Below examples use named parameters
7// Volume of Cube
8Volume = CalculateVolume(edge:5, length:0, width:0, height:0, radius:0, shapeType:Shape.Cube);
9Console.WriteLine($"Volume: {Volume:N2}");
10// Answer is Volume: 125.00
11
12// Volume of Cylinder
13Volume = CalculateVolume(radius:2, height:4, length:0, width:0, edge:0, shapeType:Shape.Cylinder);
14Console.WriteLine($"Volume: {Volume:N2}");
15// Answer is Volume: 50.27
16
17// Volume of Pyramid
18Volume = CalculateVolume(length:2, width:3, height:4, radius:0, edge:0, shapeType: Shape.Pyramid);
19Console.WriteLine($"Volume: {Volume:N2}");
20// Answer is Volume: 8.00
The other benefit is that we just need to call a single function for volume calculation and not create separate functions for different shapes.
As with all the examples above, you can provide values to only the parameters that are required, and the order of the parameters doesn't matter, as long as positional parameters are not used.
Using named parameters really simplifies things as we don’t have to worry about the order of parameters and we can specify the values for only those parameters that we want. When named parameters are used with optional parameters, the usability and the function call become easy and are much enhanced. Optional parameters are a way of saying that if you do not want to provide a value to a parameter, then we will take a default value and you can skip providing the value of that parameter during the function call.
There are two steps to this process:
1public double CalculateVolume(double length=0, double width=0, double height=0, double radius=0, double edge=1, Shape shapeType=Shape.Cube)
1// Taking all the defaults
2Volume = CalculateVolume();
3Console.WriteLine($"Volume: {Volume:N2}");
4// Answer is Volume: 1.00
5
6// Volume of Cube
7Volume = CalculateVolume(edge:5, shapeType:Shape.Cube);
8Console.WriteLine($"Volume: {Volume:N2}");
9// Answer is Volume: 125.00
10
11// Volume of Cylinder
12Volume = CalculateVolume(radius:2, height:4, shapeType:Shape.Cylinder);
13Console.WriteLine($"Volume: {Volume:N2}");
14// Answer is Volume: 50.27
15
16// Volume of Pyramid
17Volume = CalculateVolume(length:2, width:3, height:4, shapeType: Shape.Pyramid);
18Console.WriteLine($"Volume: {Volume:N2}");
19// Answer is Volume: 8.00
Rule: Optional parameters can only be defined at the end of the list, after all the required or named parameters (if any).
We now know what named parameters are and how they are used in functions. Remember, they might not be suitable for some scenarios but will mostly fit in whatever design pattern you are following. To summarize, named parameters are useful for a variety of reasons: