Writing and calling methods

Methods are type members that execute a block of statements.

A method that performs some actions but does not return a value shows this by showing that it returns the void type before the name of the method. A method that performs some actions and returns a value shows this by showing that it returns the type of that value before the name of the method.

For example, you will create two methods:

  • WriteToConsole: This will perform an action (writing a line), but it will return nothing from the method, indicated by the void keyword
  • GetOrigin: This will return a string value, indicated by the string keyword

Inside the Person class, statically import System.Console, and then add the following code:

    // methods 
    public void WriteToConsole() 
    { 
      WriteLine($"{Name} was born on {DateOfBirth:dddd, d MMMM
      yyyy}"); 
    } 
 
    public string GetOrigin() 
    { 
      return $"{Name} was born on {HomePlanet}"; 
    } 

Inside the Main method, add the following code:

    p1.WriteToConsole(); 
    WriteLine(p1.GetOrigin()); 

Run the application and view the output:

Bob Smith was born on Wednesday, 22 December 1965
Bob Smith was born on Earth

Combining multiple values with tuples

Each method can only return a single value that has a single type. That type could be a simple type, such as string in the previous example, a complex type, such as Person, or a collection type, such as List<Person>.

Imagine that we want to define a method that returns both a string and an int value. We could define a new type with a string field and an int field and return an instance of that complex type. Or we could use tuples.

Tuples have been a part of some languages such as F# since their first version, but .NET only added support for them in .NET 4.0 with the System.Tuple type, and it was only in C# 7 that the C# language added syntax support for tuples.

While adding tuple support to the C# 7 language, .NET also added a new System.ValueTuple type that is more efficient in some common scenarios than the old .NET 4.0 System.Tuple type.

Note

System.ValueTuple is not part of .NET Standard 1.6, and therefore not available by default in .NET Core 1.0 or 1.1 projects.

Referencing the System.ValueTuple package with Visual Studio 2017

In Visual Studio 2017, in Solution Explorer, in the Ch06_PacktLibrary project, right-click on Dependencies and choose Manage NuGet Packages...

Click the Browse tab, search for System.ValueTuple, select the package, and click Install, as shown in the following screenshot:

Referencing the System.ValueTuple package with Visual Studio 2017

In the Review Changes dialog, click OK.

In the License Agreement dialog, click I Accept.

Referencing the System.ValueTuple package with Visual Studio Code

In Visual Studio Code, in the Ch06_PacktLibrary project, open the Ch06_PacktLibrary.csproj file and add a package reference, as shown in the following markup:

    <Project Sdk="Microsoft.NET.Sdk"> 
 
      <PropertyGroup> 
        <TargetFramework>netstandard1.4</TargetFramework> 
      </PropertyGroup> 
 
      <ItemGroup> 
        <PackageReference Include="System.ValueTuple"                           
                          Version="4.3.0" /> 
      </ItemGroup> 
 
    </Project> 

When prompted, restore dependency packages.

In the Ch06_PeopleApp project, open the Ch06_PeopleApp.csproj file, and add the same package reference, and when prompted, restore dependency packages.

Defining methods with tuples

First, we will define a method that would work in C# 4 or later. Then we will use the new C# 7 language support.

Inside the Person class, add the following code to define two methods, the first with a return type of System.Tuple<string, int> and the second with a return type using C# 7 syntax:

    // the old C# 4 and .NET 4.0 System.Tuple type 
    public Tuple<string, int> GetFruitCS4() 
    { 
      return Tuple.Create("Apples", 5); 
    } 
 
    // the new C# 7 syntax and new System.ValueTuple type 
    public (string, int) GetFruitCS7() 
    { 
      return ("Apples", 5); 
    } 

Inside the Main method, add the following code:

    Tuple<string, int> fruit4 = p1.GetFruitCS4(); 
    WriteLine($"There are {fruit4.Item2} {fruit4.Item1}."); 
 
    (string, int) fruit7 = p1.GetFruitCS7(); 
    WriteLine($"{fruit7.Item1}, {fruit7.Item2} there are."); 

Run the application and view the output:

There are 5 Apples.
Apples, 5 there are.

Naming the fields of a tuple

To access the fields of a tuple, the default names are Item1, Item2, and so on.

You can explicitly specify the field names. Inside the Person class, add the following code to define a method:

    public (string Name, int Number) GetNamedFruit() 
    { 
      return (Name: "Apples", Number: 5); 
    } 

Inside the Main method, add the following code:

    var fruitNamed = p1.GetNamedFruit(); 
    WriteLine($"Are there {fruitNamed.Number} {fruitNamed.Name}?"); 

Run the application and view the output:

Are there 5 Apples?

Deconstructing tuples

You can also deconstruct tuples into separate variables. The deconstructing declaration has the same syntax as named field tuples, but without a variable name for the whole tuple. This has the effect of splitting the tuple into its parts and assigning those parts to new variables.

Inside the Main method, add the following code:

    (string fruitName, int fruitNumber) = p1.GetFruitCS7(); 
    WriteLine($"Deconstructed: {fruitName}, {fruitNumber}"); 

Run the application and view the output:

Deconstructed: Apples, 5

Note

Deconstruction is not just for tuples. Any type can be deconstructed if it has a Deconstructor method. You can read about this at the following link: https://docs.microsoft.com/en-us/dotnet/articles/csharp/tuples#deconstruction.

Defining and passing parameters to methods

Methods can have parameters passed to them to change their behavior. Parameters are defined a bit like variable declarations, but inside the parentheses of the method.

Inside the Person class, add the following code to define two methods, the first without parameters and the second with one parameter:

    public string SayHello() 
    { 
      return $"{Name} says 'Hello!'"; 
    } 
 
    public string SayHelloTo(string name) 
    { 
      return $"{Name} says 'Hello {name}!'"; 
    } 

Inside the Main method, add the following code:

    WriteLine(p1.SayHello()); 
    WriteLine(p1.SayHelloTo("Emily")); 

Run the application and view the output:

Bob Smith says 'Hello!'
Bob Smith says 'Hello Emily!'

Overloading methods

When typing a statement that calls a method, IntelliSense, in both Visual Studio 2017 and Visual Studio Code with the appropriate language extension installed, should show useful tooltips.

In Visual Studio 2017, you can press Ctrl + K, I or go to Edit | IntelliSense | Quick Info to see Quick Info of a method, as shown in the following screenshot:

Overloading methods

Here is the SayHelloTo method's quick info:

Overloading methods

Instead of having two different method names, we could give both methods the same name. This is allowed because the methods each have a different signature. A method signature is a list of parameter types that can be passed when calling the method.

In the Person class, change the name of the SayHelloTo method to SayHello. Now, when you view the quick info for the method, it tells you that it has one additional overload:

Overloading methods

Tip

Good Practice

Use overloaded methods to simplify your class by making it appear to have fewer methods.

Optional parameters and named arguments

Another way to simplify methods is to make parameters optional. You make a parameter optional by assigning a default value inside the method parameter list. Optional parameters must always come last in the list of parameters.

You will now create a method with three optional parameters.

Inside the Person class, add the following code:

    public void OptionalParameters(string command = "Run!",  
      double number = 0.0, bool active = true) 
    { 
      WriteLine($"command is {command}, number is {number}, active is
      {active}"); 
    } 

Inside the Main method, add the following code:

    p1.OptionalParameters(); 

Watch IntelliSense's Quick Info appear as you type the code, and you will see a tooltip, showing the three optional parameters with default values, as shown in the following screenshot:

Optional parameters and named arguments

When you run the application, you will see the following output:

command is Run!, number is 0, active is True

In the Main method, add the following line, which passes a string for the command and a double for the number parameters:

    p1.OptionalParameters("Jump!", 98.5); 

Run the application and see the output:

command is Jump!, number is 98.5, active is True

The default values for command and number have been replaced, but the default for active is still true.

Optional parameters are often combined with naming parameters when you call the method, because naming a parameter allows the values to be passed in a different order than how they were declared.

In the Main method, add the following line, which passes a string for the command and a double for the number parameters but using named parameters, so that the order they are passed can be swapped around:

    p1.OptionalParameters(number: 52.7, command: "Hide!"); 

Run the application and see the output:

command is Hide!, number is 52.7, active is True

You can even use named parameters to skip over optional parameters.

In the Main method, add the following line that passes a string for the command using positional order, skips the number parameter, and uses the named active parameter:

    p1.OptionalParameters("Poke!", active: false); 

Run the application and see the output:

command is Poke!, number is 0, active is False
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.39.144