Monday 23 February 2015

Named and optional arguments in C# programming

Welcome to Logically Proven blog.

This post demonstrates Named and Optional Arguments in C# programming.

If you worked on VBA (Visual Basic for Applications) programming earlier, then you are very familiar with optional arguments which is a very well-known feature and very useful.

Microsoft introduces optional arguments as well as named arguments with Visual C# 2010 version.

Both techniques can be used with methods, indexers, constructors, and delegates.

Now we discuss in detail about named and optional arguments.

Named Arguments:

When we are passing the arguments, it is important to always remember the order of parameters they appear in the called methods. By using named arguments, we are free from the need to remember or to look up the order of parameters of called methods. It doesn't mean that you can pass the arguments in any order, but this feature allows you to specify the parameter for each argument by parameter name.

For example, consider a function that calculates the area of a rectangle. The standard way of sending arguments for length and width are

CalculateAreaOfRectangle(20,10)

If you don't remember order of the parameters, you can send the arguments like below -

CalculateAreaOfRectangle(length: 20, width: 10);
//or
CalculateAreaOfRectangle(width:10, length: 20);
//or
CalculateAreaOfRectangle(20, width:10);   //A named argument can follow positional arguments

The following statement causes a compiler error:

CalculateAreaOfRectangle(width:20, 10); // A positional argument cannot follow a named argument

Named arguments also improve the readability of code by identifying what each argument represents.

Example:


class NamedArgExample
{
    static void Main(string[] args)
    {
        // The method can be called in the normal way, by using positional arguments.
        Console.WriteLine(CalculateAreaOfRectangle(20, 10));

        // Named arguments can be supplied for the parameters in either order.
        Console.WriteLine(CalculateAreaOfRectangle(length: 20, width: 10));
        Console.WriteLine(CalculateAreaOfRectangle(width: 10, length: 20));

        // Positional arguments cannot follow named arguments. 
        // The following statement causes a compiler error. 
        //Console.WriteLine(CalculateAreaOfRectangle(width: 20, 10)); 

        // Named arguments can follow positional arguments.
        Console.WriteLine(CalculateAreaOfRectangle(20, width: 10));
    }

    static int CalculateAreaOfRectangle(int length, int width)
    {
        return (length*width);
    }
}


Optional Arguments:

Consider a case where you don't require to send arguments for every parameter. In this scenario you can use optional arguments. Optional arguments allows you to omit arguments for some parameters. The arguments are considered as optional when the parameters are initialized to a default value or a constant expression.

Each optional parameter has a default value as part of its defintion. Because if no argument is sent for that parameter, the default value is used. A default value must be one of the following types of expressions -

1. a constant expression;
2. an expression of the form new valType(), where valType is a value type, such as an enum or a struct;
3. an expression of the form default(valType), where valType is a value type.

Optional parameters should appear only at the end of the parameter list (only after required parameters).

Consider a method with 3 parameters. Among three, first parameter is required and the rest are optional parameters.

public void Example(int required, string optionalstr = "default string",
    int optionalint = 10)

The following statement causes a compiler error. Comma-separated gaps in the argument list are not supported.

anExample.Example(3, ,4); //compiler error

You can accomplish this task by using named argument  -

anExample.Example(3, optionalint:4); //using named argument

Example:Note a constructor with named argument.


namespace OptionalArgNamespace
{
    class OptionalArgExample
    {
        static void Main(string[] args)
        {
            // Instance anExample does not send an argument for the constructor's 
            // optional parameter.
            Example anExample = new Example();
            anExample.Example(1, "One", 1);
            anExample.Example(2, "Two");
            anExample.Example(3);

            // Instance anotherExample sends an argument for the constructor's 
            // optional parameter.
            Example anotherExample = new Example("Provided name");
            anotherExample.Example(1, "One", 1);
            anotherExample.Example(2, "Two");
            anotherExample.Example(3);

            // The following statements produce compiler errors. 

            // An argument must be supplied for the first parameter, and it 
            // must be an integer. 
            //anExample.Example("One", 1);
            //anExample.Example(); 

            // You cannot leave a gap in the provided arguments.  
            //anExample.Example(3, ,4); 
            //anExample.Example(3, 4); 

            // You can use a named parameter to make the previous  
            // statement work.
            anExample.Example(3, optionalint: 4);
        }
    }

    class Example
    {
        private string _name;

        // Because the parameter for the constructor, name, has a default 
        // value assigned to it, it is optional. 
        public Example(string name = "Default name")
        {
            _name = name;
        }

        // The first parameter, required, has no default value assigned 
        // to it. Therefore, it is not optional. Both optionalstr and  
        // optionalint have default values assigned to them. They are optional. 
        public void Example(int required, string optionalstr = "default string",
            int optionalint = 10)
        {
            Console.WriteLine("{0}: {1}, {2}, and {3}.", _name, required, optionalstr,
                optionalint);
        }
    }

    // The output from this example is the following: 
    // Default name: 1, One, and 1. 
    // Default name: 2, Two, and 10. 
    // Default name: 3, default string, and 10. 
    // Provided name: 1, One, and 1. 
    // Provided name: 2, Two, and 10. 
    // Provided name: 3, default string, and 10. 
    // Default name: 3, default string, and 4.

}


Please write your comments if you find anything is incorrect or do you want to share more information about the topic discussed above.

Logically proven
Learn, Teach, Share

Karthik Byggari

Author & Editor

Computer Science graduate, Techie, Founder of logicallyproven, Love to Share and Read About pprogramming related things.

0 comments:

Post a Comment

 
biz.