Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
C# 7 and .NET Core Cookbook
C# 7 and .NET Core Cookbook

C# 7 and .NET Core Cookbook: Serverless programming, Microservices and more , Second Edition

eBook
€28.99 €32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

C# 7 and .NET Core Cookbook

New Features in C# 7.0

In this first chapter, we will take a look at the C# 7.0 features by covering them in the following recipes:

  • Working with Tuples - getting started
  • Working with Tuples - going deeper
  • Pattern matching
  • Out variables
  • Deconstruction
  • Local functions
  • Improvements to literals
  • Ref returns and locals
  • Generalized async return types
  • Expression bodies for accessors, constructors, and finalizers
  • throw expressions

Introduction

C# 7.0 brings a lot of new functionality to the C# language. If you were left wanting more after the release of C# 6.0, then C# 7.0 will not disappoint you at all. It focuses on consuming data, simplifying code, and improving performance. Mads Torgersen who is the C# Program Manager noted that C# 7.0's biggest feature by far is Tuples. The other is pattern matching. These two features (as well as the others) were met with enthusiasm from C# developers worldwide. It is, therefore, no guess that developers will immediately start implementing these new features introduced in C# 7.0. It will, therefore, be very beneficial to get to grips with what C# 7.0 has to offer and implement the new language features in your development projects as soon as possible.

Throughout this book, I will be using the release candidate of Visual Studio 2017. Some features and methods of doing things might change between the time of writing and the final release of Visual Studio 2017.

Working with Tuples - getting started

I have come across many instances where I wanted to return more than one value from a method. As Mads Torgersen pointed out, the existing options available to developers are not optimal. C# 7.0 has, therefore, introduced Tuple types and Tuple literals to allow developers an easy way of returning multiple values from methods. Developers can also rest easy when creating Tuples. Tuples are structs, which are value types. This means that they are created locally and are passed by copying the contents. Tuples are also mutable and Tuple elements are public mutable fields. I am personally very excited about using Tuples. Let's explore Tuples in closer detail in the following recipe.

Getting ready

Start off by creating a regular console application in Visual Studio 2017. Simply call the project you create cookbook. Before I can jump into using Tuples in C# 7.0, I need to add in a NuGet package. Bear in mind that I am using the release candidate of Visual Studio. This process might change between now and the final release of the product.

  1. To do this, head on over to Tools, NuGet Package Manager and then, click on Manage NuGet Packages for Solution....
  1. Select the Browse tab and type in ValueTuple in the search box. The System.ValueTuple by Microsoft NuGet package should be displayed. Select the cookbook project under Manage Packages for Solution and click on the Install button.
Take note that I am using Visual Studio 2017 RC while writing portions of this book. You probably will not need to add System.ValueTuple from NuGet some time in the future after the final release. Adding System.ValueTuple from NuGet might, however, remain a requirement. Only time will tell.
  1. Visual Studio will now show you a prompt to review the changes you are about to make to your project. Just click on the OK button. Lastly, you will need to provide the License Agreement required by Microsoft. Just click on the I Accept button. Visual Studio will now start the NuGet package installation. It will show you its progress in the Output window.

After all this is complete, my Visual Studio solution looks as follows:

You will now be ready to create your first method that works with Tuples. Let's see how to do that next.

How to do it...

  1. Start off by creating a new class in the Program.cs file of your Visual Studio console application. You can call your class anything, but for the purposes of this book I will simply be calling my class Chapter1. Your code should now look as follows:
        namespace cookbook
{
class Program
{
static void Main(string[] args)
{

}
}

public class Chapter1
{

}
}
  1. This is the format we will be using throughout this chapter. Let's assume that we want to write a method that needs to calculate the average score for a variable number of students. No grade has the same number of students in each class. Therefore, we want our method to return the number of students in the class for the calculated average score. Change the static void main method to contain a list of scores. We are also creating a new instance of the Chapter1 class and calling the method GetAverageAndCount(), which will be used to return the two values we need.
I will be hardcoding this for illustration purposes; in reality, though these scores can be for any number of students. Be sure to add the values exactly as I have in the code listing as I will be illustrating a final gotcha at the end of this recipe.
        static void Main(string[] args)
{
int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24 };
Chapter1 ch1 = new Chapter1();
var s = ch1.GetAverageAndCount(scores);
}
  1. It is here that we can use the power of Tuples to declare the GetAverageAndCount() method in the Chapter1 class. It accepts an array of integer scores and looks as follows:
        public (int, int) GetAverageAndCount(int[] scores)
{

}
  1. Pay close attention to the return Tuple type (int, int). We are only returning two values from the GetAverageAndCount() method, but in reality you can return several values if needed. In order to run your code sample, we will create a dummy implementation of this method. To do this, just include a Tuple literal that returns two zeros.
        public (int, int) GetAverageAndCount(int[] scores)
{
var returnTuple = (0, 0);
return returnTuple;
}
  1. Go back to the static void Main method where the Tuple returning method is called and write code to consume the return values. Every Tuple you create will expose members called Item1, Item2, Item3, and so on. These are used to get the values returned from a Tuple returning method.
        static void Main(string[] args)
{
int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24 };
Chapter1 ch1 = new Chapter1();
var s = ch1.GetAverageAndCount(scores);
WriteLine($"Average was {s.Item1} across {s.Item2} students");
ReadLine();
}
  1. Be sure to add the following using the directive before the namespace.
        using static System.Console;
  1. You will notice that we used s.Item1 and s.Item2 to reference the return values returned from our GetAverageAndCount() method. While this is totally legal, it isn't very descriptive and makes it difficult to infer the usage of the variable returned. It basically means that you would have to remember that Item1 is the average value and Item2 is the count value. Perhaps, it is the other way around? Is Item1 the count and Item2 the average? It really depends on what you are doing inside the GetAverageAndCount() method (which can change over time). Our Tuple returning method can therefore be enhanced as follows:
        public (int average, int studentCount) 
GetAverageAndCount(int[] scores)
{
var returnTuple = (0, 0);
return returnTuple;
}
  1. The Tuple return type can now declare variable names for its elements. This makes it easy for the caller of the GetAverageAndCount() method to know which value is which. You can still keep on using s.Item1 and s.Item2, but it is now much easier to change the calling code in the static void Main method accordingly:
        static void Main(string[] args)
{
int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24 };
Chapter1 ch1 = new Chapter1();
var s = ch1.GetAverageAndCount(scores);
WriteLine($"Average was {s.average} across {
s.studentCount} students");
ReadLine();
}
  1. Changing the interpolated string in WriteLine, we see that the usage of the values returned by the Tuple is much clearer. You now know that the first value is the average and that the second value is the count of the students used to calculate the average. Tuples, however, allow developers more flexibility. Remember the Tuple literal in the GetAverageAndCount() method? We simply added this in the dummy implementation as follows:
        var returnTuple = (0, 0);
  1. C# 7.0 also allows developers to add names to Tuple literals. Inside the GetAverageAndCount() method, change your Tuple literal as follows:
        var returnTuple = (ave:0, sCount:0);
  1. I have just named the first value a name of ave (for average) and the second sCount (for student count). This is some really exciting stuff! After you have modified your Tuple literal, your dummy implementation of the GetAverageAndCount() method should look as follows:
        public (int average, int studentCount) 
GetAverageAndCount(int[] scores)
{
var returnTuple = (ave:0, sCount:0);
return returnTuple;
}
Tuples play really nicely together. As long as the Tuple types match up, you do not have to worry that the ave and sCount names in the Tuple literal don't match the average and studentCount names of the return type.

How it works...

So far in this recipe, we have seen that Tuples give developers a lot of flexibility when you need to return several values from a method. While the dummy implementation of GetAverageAndCount() simply returns the zero-valued Tuple literal, it gives you some idea how Tuples are wired up. This recipe is the foundation for the next recipe. I encourage you to go through both recipes thoroughly in order to gain the full benefit from understanding Tuples and how to use them.

Working with Tuples - going deeper

I will now start adding more meat to the dummy implementation of the GetAverageAndCount() method we created in the previous recipe. If you are new to Tuples, and have not worked through the previous recipe, I encourage you to do so first before starting to work through this recipe.

Getting ready

You need to have completed the code steps in the recipe Working with Tuples - getting started, in order to work through this recipe. Ensure that you have added the required NuGet package as specified in the previous recipe.

How to do it...

  1. Let's take a look at the calling code again. We can further simplify the code in the static void Main method by getting rid of the var s. When we called the GetAverageAndCount() method, we returned the Tuple into var s.
        var s = ch1.GetAverageAndCount(scores);
  1. We do not have to do this. C# 7.0 allows us to immediately split the Tuple into its respective parts as follows:
        var (average, studentCount) = ch1.GetAverageAndCount(scores);
  1. We can now consume the values returned by the Tuple directly as follows:
        WriteLine($"Average was {average} across {studentCount} students");
  1. Before we implement the GetAverageAndCount() method, make sure that your static void Main method looks as follows:
        static void Main(string[] args)
{
int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24 };
Chapter1 ch1 = new Chapter1();
var (average, studentCount) = ch1.GetAverageAndCount(scores);
WriteLine($"Average was {average} across {
studentCount} students");
ReadLine();
}
  1. Secondly, ensure that the GetAverageAndCount() method's dummy implementation looks as follows:
        public (int average, int studentCount) 
GetAverageAndCount(int[] scores)
{
var returnTuple = (ave:0, sCount:0);
return returnTuple;
}
  1. Go ahead and run your console application. You will see that the two values, average and studentCount are returned from our dummy implementation of GetAverageAndCount().
  1. The values are obviously still zero because we have not defined any logic inside the method. We will do this next. Before we write the implementation, make sure that you have added the following using statement:
        using System.Linq;
  1. Because we are using an array of integers for the variable scores, we can easily return the results we need. LINQ allows us to get the sum of the student scores contained in the scores array, simply by writing scores.Sum(). We can also easily get the count of the student scores from the scores array by writing scores.Count(). The average, therefore, would logically be the sum of the scores divided by the count of the student scores (scores.Sum()/scores.Count()). We then put the values into our returnTuple literal as follows:
        public (int average, int studentCount) 
GetAverageAndCount(int[] scores)
{
var returnTuple = (ave:0, sCount:0);
returnTuple = (returnTuple.ave = scores.Sum()/scores.Count(),
returnTuple.sCount = scores.Count());
return returnTuple;
}
  1. Run your console application to see the result displayed as follows:
  1. We can see that the class average isn't too great, but that is of little importance to our code. Another piece of code that isn't too great is this line:
        returnTuple = (returnTuple.ave = scores.Sum()/scores.Count(), 
returnTuple.sCount = scores.Count());
  1. It is clunky and doesn't read very nicely. Let's simplify this a bit. Remember that I mentioned previously that Tuples play nicely together as long as their types match? This means that we can do this:
        public (int average, int studentCount)
GetAverageAndCount(int[] scores)
{
var returnTuple = (ave:0, sCount:0);
returnTuple = (scores.Sum()/scores.Count(), scores.Count());
return returnTuple;
}
  1. Run your console application again and notice that the result stays the same:
  1. So why did we give the Tuple literal names to begin with? Well, it allows you to reference them easily within your GetAverageAndCount() method. It is also really very useful when using a foreach loop in your method. Consider the following scenario. In addition to returning the count and average of the student scores, we need to return an additional Boolean value if the class average is below a certain threshold. For this example, we will be making use of an extension method called CheckIfBelowAverage() and it will take a threshold value as an integer parameter. Start off by creating a new static class called ExtensionMethods.
        public static class ExtensionMethods
{

}
  1. Inside the static class, create a new method called CheckIfBelowAverage() and pass it an integer value called threshold. The implementation of this extension method is pretty straightforward, so I will not go into much detail here.
        public static bool CheckIfBelowAverage(
this int classAverage, int threshold)
{
if (classAverage < threshold)
{
// Notify head of department
return true;
}
else
return false;
}
  1. In the Chapter1 class, overload the GetAverageAndCount() method by changing its signature and passing a value for the threshold that needs to be applied. You will remember that I mentioned that a Tuple return type method can return several values, not just two. In this example, we are returning a third value called belowAverage that will indicate if the calculated class average is below the threshold value we pass to it.
        public (int average, int studentCount, bool belowAverage) 
GetAverageAndCount(int[] scores, int threshold)
{

}
  1. Modify the Tuple literal, adding it to subAve ,and default it to true, because a class average of zero will logically be below any threshold value we pass to it.
        var returnTuple = (ave: 0, sCount: 0, subAve: true);
  1. We can now call the extension method CheckIfBelowAverage() on the returnTuple.ave value we defined in our Tuple literal and pass through it the threshold variable. Just how useful giving the Tuple literal logical names becomes evident when we use it to call the extension method.
        returnTuple = (scores.Sum() / scores.Count(), scores.Count(), 
returnTuple.ave.CheckIfBelowAverage(threshold));
  1. Your completed GetAverageAndCount() method will now look as follows:
        public (int average, int studentCount, bool belowAverage) 
GetAverageAndCount(int[] scores, int threshold)
{
var returnTuple = (ave: 0, sCount: 0, subAve: true);
returnTuple = (scores.Sum() / scores.Count(), scores.Count(),
returnTuple.ave.CheckIfBelowAverage(threshold));
return returnTuple;
}
  1. Modify your calling code to make use of the overloaded GetAverageAndCount() method as follows:
        int threshold = 51;
var (average, studentCount, belowAverage) = ch1.GetAverageAndCount(
scores, threshold);
  1. Lastly, modify the interpolated string to read as follows:
        WriteLine($"Average was {average} across {studentCount}
students. {(average < threshold ?
" Class score below average." :
" Class score above average.")}");
  1. The completed code in your static void Main method should now look as follows:
        static void Main(string[] args)
{
int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24 };
Chapter1 ch1 = new Chapter1();
int threshold = 51;
var (average, studentCount, belowAverage) =
ch1.GetAverageAndCount(scores, threshold);
WriteLine($"Average was {average} across {studentCount}
students. {(average < threshold ?
" Class score below average." :
" Class score above average.")}");
ReadLine();
}
  1. Run your console application to view the result.
  1. To test that the ternary operator ? is working correctly inside the interpolated string, modify your threshold value to be lower than the average returned.
        int threshold = 40;
  1. Running your console application a second time will result in a passing average class score.
  1. Finally, there is one glaring problem that I need to highlight with this recipe. It is one that I am sure you have picked up on already. If not, don't worry. It is a bit of a sneaky one. This is the gotcha I was referring to at the start of this recipe and I intentionally wanted to include it to illustrate the bug in the code. Our array of student scores is defined as follows:
        int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24 };
  1. The sum of these equals to 400 and because there are only 8 scores, the value will work out correctly because it divides up to a whole number (400 / 8 = 50). But what would happen if we had another student score in there? Let's take a look. Modify your scores array as follows:
        int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24, 49 };
  1. Run your console application again and look at the result.
  1. The problem here is that the average is incorrect. It should be 49.89. We know that we want a double (unless your application of this is intended to return an integer). We, therefore, need to pay attention to casting the values correctly in the return type and the Tuple literal. We also need to handle this in the extension method CheckIfBelowAverage(). Start off by changing the extension method signature as follows to act on a double.
        public static bool CheckIfBelowAverage(
this double classAverage, int threshold)
{

}
  1. Then we need to change the data type of the average variable in the Tuple method return type as follows:
        public (double average, int studentCount, bool belowAverage) 
GetAverageAndCount(int[] scores, int threshold)
{

}
  1. Then, modify the Tuple literal so ave is a double by using ave: 0D.
        var returnTuple = (ave: 0D, sCount: 0, subAve: true);
  1. Cast the average calculation to a double.
        returnTuple = ((double)scores.Sum() / scores.Count(),
scores.Count(),
returnTuple.ave.CheckIfBelowAverage(threshold));
  1. Add the following using statement to your application:
        using static System.Math;
  1. Lastly, use the Round method to format the average variable in the interpolated string to two decimals.
        WriteLine($"Average was {Round(average,2)} across {studentCount}
students. {(average < threshold ?
" Class score below average." :
" Class score above average.")}");
  1. If everything is done correctly, your GetAverageAndCount() method should look as follows:
        public (double average, int studentCount, bool belowAverage) 
GetAverageAndCount(int[] scores, int threshold)
{
var returnTuple = (ave: 0D, sCount: 0, subAve: true);
returnTuple = ((double)scores.Sum() / scores.Count(),
scores.Count(),
returnTuple.ave.CheckIfBelowAverage(
threshold));
return returnTuple;
}
  1. Your calling code should also look as follows:
        static void Main(string[] args)
{
int[] scores = { 17, 46, 39, 62, 81, 79, 52, 24, 49 };
Chapter1 ch1 = new Chapter1();
int threshold = 40;
var (average, studentCount, belowAverage) =
ch1.GetAverageAndCount(scores, threshold);
WriteLine($"Average was {Round(average,2)} across
{studentCount} students. {(average < threshold ?
" Class score below average." :
" Class score above average.")}");
ReadLine();
}
  1. Run the console application to see the correctly rounded average for the student scores.

How it works...

Tuples are structs, and therefore value types that are created locally. You, therefore, do not have to worry about using and assigning Tuples on-the-fly or that it creating a lot of allocations. Their contents are merely copied when passed. Tuples are mutable and the elements are publicly scoped mutable fields. Using the code example in this recipe, I can, therefore, do the following:

returnTuple = (returnTuple.ave + 15, returnTuple.sCount - 1);

C# 7.0 is allowing me to first update the average value (shifting the average up) and then decrementing the count field. Tuples are a very powerful feature of C# 7.0, and it will be of great benefit to many developers when implemented it correctly.

Pattern matching

C# 7.0 introduces an aspect common to functional programming languages with pattern matching. This new kind of construct can test values in different ways. To accomplish this, two language constructs in C# 7.0 have been enhanced to take advantage of patterns. These are as follows:

  • The is expression
  • The case clause in switch statements

With regard to the is expression, developers can now have a pattern on the right instead of just a type. When it comes to switch statements, the case clause can now match on patterns. The switch statement is no longer limited to primitive types and can switch on anything. Let's start by looking at the is expression.

Getting ready

To illustrate the concept of pattern matching, assume the following scenario. We have two object types called Student and Professor. We want to minimize code, so we want to create a single method to output the data from the object passed to it. This object can be a Student or a Professor object. The method needs to figure out which object it is working with and act accordingly. But first, we need to do a few things inside our console application to set things up:

  1. Ensure that you have added the following using statement.
        using System.Collections.Generic;
  1. You now need to create two new classes called Student and Professor. The code for the Student class needs to look as follows:
        public class Student
{
public string Name { get; set; }
public string LastName { get; set; }
public List<int> CourseCodes { get; set; }
}
  1. Next, the code for the Professor class needs to look as follows:
        public class Professor
{
public string Name { get; set; }
public string LastName { get; set; }
public List<string> TeachesSubjects { get; set; }
}

To understand where we are going with pattern matching, we first need to understand where we have come from. I will start the next section off by showing you how developers might have written this code before C# 7.0.

How to do it...

  1. In the Chapter1 class, create a new method called OutputInformation() that takes a person object as parameter.
        public void OutputInformation(object person)
{

}
  1. Inside this method, we would need to check what type of object is passed to it. Traditionally, we would need to do the following:
        if (person is Student)
{
Student student = (Student)person;
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for courses {String.Join<int>(
", ", student.CourseCodes)}");
}

if (person is Professor)
{
Professor prof = (Professor)person;
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>(",", prof.TeachesSubjects)}");
}
  1. We have two if statements. We are expecting either a Student object or a Professor object. The complete OutputInformation() method should look as follows:
        public void OutputInformation(object person)
{
if (person is Student)
{
Student student = (Student)person;
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for courses {String.Join<int>
(", ", student.CourseCodes)}");
}
if (person is Professor)
{
Professor prof = (Professor)person;
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>
(",", prof.TeachesSubjects)}");
}
}
  1. Calling this method from the static void Main is easy enough. The objects are similar, but differ in the list they contain. A Student object exposes a list of course codes, while a Professor exposes a list of subjects taught to students.
        static void Main(string[] args)
{
Chapter1 ch1 = new Chapter1();

Student student = new Student();
student.Name = "Dirk";
student.LastName = "Strauss";
student.CourseCodes = new List<int> { 203, 202, 101 };

ch1.OutputInformation(student);

Professor prof = new Professor();
prof.Name = "Reinhardt";
prof.LastName = "Botha";
prof.TeachesSubjects = new List<string> {
"Mobile Development", "Cryptography" };

ch1.OutputInformation(prof);
}
  1. Run the console application and see the OutputInformation() method in action.
  1. While the information we see in the console application is what we expect, we can simplify the code in the OutputInformation() method much more with pattern matching. To do this, modify the code as follows:
        if (person is Student student)
{

}
if (person is Professor prof)
{

}
  1. The first if expression checks to see if the object person is of type Student. If so, it stores that value in the student variable. The same logic is true for the second if expression. If true, the value of person is stored inside the variable prof. For code execution to reach the code between the curly braces of each if expression, the condition had to evaluate to true. We can, therefore, dispense with the cast of the person object to a Student or Professor type, and just use the student or prof variable directly, like so:
        if (person is Student student)
{
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for courses {String.Join<int>
(", ", student.CourseCodes)}");
}
if (person is Professor prof)
{
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>
(",", prof.TeachesSubjects)}");
}
  1. Running the console application again, you will see that the output is exactly the same as before. We have, however, written better code that uses type pattern matching to determine the correct output to display.
  1. Patterns, however, don't stop there. You can also use them in constant patterns, which are the simplest type of pattern to use. Let's take a look at the check for the constant null. With pattern matching we can enhance our OutputInformation() method as follows:
        public void OutputInformation(object person)
{
if (person is null)
{
WriteLine($"Object {nameof(person)} is null");
}
}
  1. Change the code that is calling the OutputInformation() method and set it to null.
        Student student = null;
  1. Run your console application and see the message displayed.
It is good practice to use the nameof keyword here. If the variable name person ever has to change, the corresponding output will be changed also.
  1. Lastly, switch statements in C# 7.0 have been improved to make use of pattern matching. C# 7.0 allows us to switch on anything, not just primitive types and strings. The case clauses now make use of patterns, which is really exciting. Let's have a look at how to implement this in the following code examples. We will keep using the Student and Professor types to illustrate the concept of pattern matching in switch statements. Modify the OutputInformation() method and include the boilerplate switch statement as follows. The switch statement still has defaults, but it can now do so much more.
        public void OutputInformation(object person)
{
switch (person)
{
default:
WriteLine("Unknown object detected");
break;
}
}
  1. We can expand the case statement to check for the Professor type. If it matches an object to the Professor type, it can act on that object and use it as a Professor type in the body of the case statement. This means we can call the Professor-specific TeachesSubjects property. We do it like this:
        switch (person)
{
case Professor prof:
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>
(",", prof.TeachesSubjects)}");
break;
default:
WriteLine("Unknown object detected");
break;
}
  1. We can also do the same for Student types. Change the code of the switch as follows:
        switch (person)
{
case Student student:
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for courses {String.Join<int>
(", ", student.CourseCodes)}");
break;
case Professor prof:
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>
(",", prof.TeachesSubjects)}");
break;
default:
WriteLine("Unknown object detected");
break;
}
  1. One final (and great) feature of case statements remains to be illustrated. We can also implement a when condition, similar to what we saw in C# 6.0 with exception filters. The when condition simply evaluates to a Boolean and further filters the input that it triggers on. To see this in action, change the switch accordingly:
        switch (person)
{
case Student student when (student.CourseCodes.Contains(203)):
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for course 203.");
break;
case Student student:
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for courses {String.Join<int>
(", ", student.CourseCodes)}");
break;
case Professor prof:
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>(",",
prof.TeachesSubjects)}");
break;
default:
WriteLine("Unknown object detected");
break;
}
  1. Lastly, to come full circle and check for null values, we can modify our switch statement to cater for those too. The completed switch statement is, therefore, as follows:
        switch (person)
{
case Student student when (student.CourseCodes.Contains(203)):
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for course 203.");
break;
case Student student:
WriteLine($"Student {student.Name} {student.LastName}
is enrolled for courses {String.Join<int>
(", ", student.CourseCodes)}");
break;
case Professor prof:
WriteLine($"Professor {prof.Name} {prof.LastName}
teaches {String.Join<string>
(",", prof.TeachesSubjects)}");
break;
case null:
WriteLine($"Object {nameof(person)} is null");
break;
default:
WriteLine("Unknown object detected");
break;
}
  1. Running the console application again, you will see that the first case statement containing the when condition is triggered for the Student type.

How it works...

With pattern matching, we saw that patterns are used to test whether a value is of a certain type.

You will also hear some developers say that they test whether the value has a certain shape.

When we find a match we can get to the information specific to that type (or shape). We saw this in the code where we accessed the CourseCodes property, which was specific to the Student type and the TeachesSubjects property, which was specific to the Professor type.

Lastly, you now need to pay careful attention to the order of your case statements, which now matters. The case statement that uses the when clause is more specific than the statement that simply checks for a Student type. This means that the when case needs to happen before the Student case because both of these cases are of type Student. If the Student case happens before the when clause, it will never trigger the switch for Students that have course code 203.

Another important thing to remember is that the default clause will always be evaluated last, irrespective of where it appears in the switch statement. It is, therefore, good practice to write it as the last clause in a switch statement.

Left arrow icon Right arrow icon

Key benefits

  • Easy-to-follow recipes to get you up-and-running with the new features of C# 7 and .NET Core 1.1
  • Practical solutions to assist you with microservices and serverless computing in C#
  • Explore the new Visual Studio environment and write more secure code in it

Description

C# has recently been open-sourced and C# 7 comes with a host of new features for building powerful, cross-platform applications. This book will be your solution to some common programming problems that you come across with C# and will also help you get started with .NET Core 1.1. Through a recipe-based approach, this book will help you overcome common programming challenges and get your applications ready to face the modern world. We start by running you through new features in C# 7, such as tuples, pattern matching, and so on, giving you hands-on experience with them. Moving forward, you will work with generics and the OOP features in C#. You will then move on to more advanced topics, such as reactive extensions, Regex, code analyzers, and asynchronous programming. This book will also cover new, cross-platform .NET Core 1.1 features and teach you how to utilize .NET Core on macOS. Then, we will explore microservices as well as serverless computing and how these benefit modern developers. Finally, you will learn what you can do with Visual Studio 2017 to put mobile application development across multiple platforms within the reach of any developer.

Who is this book for?

The book will appeal to C# and .NET developers who have a basic familiarity with C# and the Visual Studio 2015 environment

What you will learn

  • Writing better and less code to achieve the same result as in previous versions of C#
  • Working with analyzers in Visual Studio
  • Working with files, streams, and serialization
  • Writing high-performant code in C# and understanding multi-threading
  • Demystifying the Rx library using Reactive extensions
  • Exploring .Net Core 1.1 and ASP.NET MVC
  • Securing your applications and learning new debugging techniques
  • Designing and building a microservice architecture
  • Using Azure and AWS for serverless computing with C#
Estimated delivery fee Deliver to Spain

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 25, 2017
Length: 628 pages
Edition : 2nd
Language : English
ISBN-13 : 9781787286276
Vendor :
Microsoft
Category :
Languages :
Concepts :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Spain

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Publication date : Apr 25, 2017
Length: 628 pages
Edition : 2nd
Language : English
ISBN-13 : 9781787286276
Vendor :
Microsoft
Category :
Languages :
Concepts :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 134.97
.NET Design Patterns
€32.99
C# 7.1 and .NET Core 2.0 ??? Modern Cross-Platform Development
€59.99
C# 7 and .NET Core Cookbook
€41.99
Total 134.97 Stars icon

Table of Contents

16 Chapters
New Features in C# 7.0 Chevron down icon Chevron up icon
Classes and Generics Chevron down icon Chevron up icon
Object-Oriented Programming in C# Chevron down icon Chevron up icon
Code Analyzers in Visual Studio Chevron down icon Chevron up icon
Regular Expressions Chevron down icon Chevron up icon
Working with Files, Streams, and Serialization Chevron down icon Chevron up icon
Making Apps Responsive with Asynchronous Programming Chevron down icon Chevron up icon
High Performance Programming Using Parallel and Multithreading in C# Chevron down icon Chevron up icon
Composing Event-Based Programs Using Reactive Extensions Chevron down icon Chevron up icon
Exploring .NET Core 1.1 Chevron down icon Chevron up icon
ASP.NET Core on the MVC Framework Chevron down icon Chevron up icon
Choosing and Using a Source Control Strategy Chevron down icon Chevron up icon
Creating a Mobile Application in Visual Studio Chevron down icon Chevron up icon
Writing Secure Code and Debugging in Visual Studio Chevron down icon Chevron up icon
Creating Microservices on Azure Service Fabric Chevron down icon Chevron up icon
Azure and Serverless Computing Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.3
(6 Ratings)
5 star 33.3%
4 star 0%
3 star 33.3%
2 star 33.3%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




wynix Jun 08, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Easy to understand, but very basic, definitely for learners.
Amazon Verified review Amazon
Thor Kornbrek Sep 19, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
This book provides content that can improve any developers game. There are a number of areas covered that I had been interested in but not had the time to really work with: Cordova, Asp.Net Core, and Azure Functions. This book delivers enough examples to get started in those areas and the vocabulary to further research where needed.I am sure you will find something to stretch your skills in this text. The power of C# and .Net Core is clearly demonstrated with screen-shots and step by step examples. I am going to keep a copy of this around as a reference as well.
Amazon Verified review Amazon
Bharat Nov 08, 2018
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
Pages are not as good as expected
Amazon Verified review Amazon
Amazon Customer Oct 25, 2017
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
Its easy to read and need less time to finish. Around 600 pages but less content. Page content is very less most of the pages have just dialog box or image only.
Amazon Verified review Amazon
Håvard Oct 21, 2018
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
The overall consept of this book is good. I have read a few chapters which gave me some valuable input. I skipped to the chapter about regular expressions, and started following the examples given in the text.That's when trouble started. The code for date validation and text sanitation given in the book will not work. The (not so) funny thing is that there is actually two lines for date validation which show a pattern that will work. But the portion saying something like "this is how it should look" will never work.If you download the source code, there it seems as if you will find working examples.Two stars, errors like this should have been found before this book hit the market. It seems as if the Packt books are rushed through the system, with not enough time for QA.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela