March 19, 2017

Awesome New Language Features in C# 7.0 – Part 2

This post is the second part of the two-part blog post on new features in C# 7.0. Please read the previous post for the following topics.

  • Pattern Matching
  • Switch Statement
  • Local Functions
  • Tuples

Out Variables

Have you ever thought that having to declare a variable to use as an out variable is a pain in the neck? Well, you’re in luck, C# 7.0 lets you declare them inline! Look at the following old and new syntax.

    class Program
    {
        static void Main(string[] args)
        {
            // C# 6.0
            string a = string.Empty;
            OutVariableTest(out a);
            Console.WriteLine(a);

            // C# 7.0
            OutVariableTest(out string b);
            Console.WriteLine(b);
        }

        public static void OutVariableTest(out string value)
        {
            value = "some string value";
        }
    }

One thing to note is that you cannot use var to declare the variables inline, you need to use the actual type.

Deconstruction

If you haven’t read about the new tuple features in C#, I recommend that you read the previous blog post first. Consider the following example where the GetEmployeeAddress() method that returns a tuple.

class Program
{
	static void Main(string[] args)
	{
		//Syntax 1
		(string streetNumber1, string streetName1, string suburb1, string postcode1, string state1) = GetEmployeeAddress(1); // Deconstructing by declaration

		//Syntax 2
		(var streetNumber2, var streetName2, var suburb2, var postcode2, var state2) = GetEmployeeAddress(1); // Syntax with var inside

		//Syntax 3
		var (streetNumber3, streetName3, suburb3, postcode3, state3) = GetEmployeeAddress(1); // Syntax with var outside

		//Syntax 4
		string streetNumber4, streetName4, suburb4, postcode4, state4;

		(streetNumber4, streetName4, suburb4, postcode4, state4) = GetEmployeeAddress(1); // Deconstructing by assignment

		Console.WriteLine($"Employee Address : {streetNumber1}, {streetName1} {suburb1} {postcode1} {state1}.");

		Console.ReadKey();
	}

	public static
		(string streetNumber, string streetName, string suburb, string postcode, string state)
		GetEmployeeAddress(int employeeId) // tuple return type
	{
		// retrieve data by employeeId from data store.
		return ("111", "Plenty Road", "Mill Park", "3083", "Victoria");
	}
}

The code example above is pretty self-explanatory, all four of the syntax options achieve the same end results. I would suggest that if you are going to use tuples as return types often, for the sake of clarity and consistency stick to one approach within your codebase.

The Deconstruct Method

Deconstruction is not only available for tuples. You can “deconstruct” types that you create as well. See the following example.

class Program
{
	public class Employee
	{
		public string FirstName { get; set; }
		public string MiddleName { get; set; }
		public string LastName { get; set; }

		// Constructor 1
		public Employee(string firstName, string lastName)
		{
			FirstName = firstName;
			LastName = lastName;
		}

		// Constructor 2
		public Employee(string firstName, string middleName, string lastName)
		{
			FirstName = firstName;
			MiddleName = middleName;
			LastName = lastName;
		}

		// Deconstructor 1
		public void Deconstruct(out string firstName, out string lastName)
		{
			firstName = FirstName; lastName = LastName;
		}

		// Deconstructor 2
		public void Deconstruct(out string firstName, out string middleName, out string lastName)
		{
			firstName = FirstName; middleName = MiddleName; lastName = LastName;
		}
	}

	static void Main(string[] args)
	{
		var employee1 = new Employee("Floyd", "Lawton");
		var employee2 = new Employee("Oswald", "Chesterfield", "Cobblepot");

		var (firstName1, lastName1) = employee1; // Deconstructor in action
		var (firstName2, middleName2, lastName2) = employee2; // Deconstructor in action

		Console.WriteLine($"Employee 1 : {firstName1} {lastName1}");
		Console.WriteLine($"Employee 2 : {firstName2} {middleName2} {lastName2}");
	}
}

The above example demonstrates how two constructors and deconstructors work. You can observe that declarations for the constructors and deconstructors are symmetrical. This approach is the desired method to follow when declaring your classes. Here again, you can use the four different deconstruction techniques that I outlined earlier.

Digit Separator

This feature is useful if you have long numeric values in your code. Now you can separate digits with an underscore to improve readability. Adding the digit separator does not change the value of the variable in any way, it’s just syntactic sugar. See examples below.

// float example
 float number1 = 89587722.787f; // without digit seperator
 float number2 = 89_587_722.787f; // with digit seperator

 // integer example
 int number3 = 87542466; // without digit seperator
 int number4 = 87_542_466; // with digit seperator

So there we are, another set of new features in C# 7.0, I hope that I have been informative in this post and hoping to add a few more posts on this topic in the future.

Related posts: