Pages

C# Features Through the History - Version 6.0

The main features of version 6.0, available for you now!



The version 6.0 of the C# Language was released with Visual Studio 2015, following the version 4.6 and now, supporting the brand new .NET Core.

How to use the examples 

The examples are available here. You can open the solution and play around. Just uncomment the code and have fun! 



Read-Only Auto Properties

The read-only auto-properties allows the support of the language to create immutable types. You can create a get property, with the only accessor to be changed on the constructor, or with the new auto-property initializers.

        
    internal class Product {
        //readonly properties 
        public string Name { get; }
        public bool InStock { get; }

        public Product(string name)
        {
            this.Name = name;
        }
    }    
        
	var product = new Product("Product 1");

	Console.WriteLine($"{product.Name} {product.InStock}");

	product.InStock = true; //error - readonly property

Auto-Property Initializers

The version 3.0 of C# brought the possibility to define properties in an easier way, the auto properties. Now, with version 6.0, we have the possibility to create the property and add a value for it, without the need to use the constructor of the class to define some value for a get property, for example.

        
    internal class Customer {
        //initializing property with values
        public string Name { get; set; } = "John";
        public string LastName { get; } = "Nash";
        public int Age { get; } = 55;
    }
        
	var customer = new Customer();

	Console.WriteLine($"{customer.Name} {customer.LastName} - {customer.Age}.");

	customer.Name = "David";

	customer.LastName = "Beckham"; //error: readonly property
	customer.Age = 48;             //error: readonly property 

Static Using

With this new kind of using clause, it's possible to import static members into scope.

        
	//adding static
	using static System.Math;
	using static System.Console;
        
	var result = Pow(5, 2);

	Write($"Five squared is {result}.");

Null Conditional Operator

This operator turns the null check easier and fluid. If we are working with properties from classes, instead of returning an exception for null values it'll return null, or the default property of some value (e.g. 0 for an int property).

        
	//definition of classes and properties
    internal class Book {
        public string Name { get; set; }
        public int Pages { get; set; }
        public Author[] Authors { get; set; }
        public Publisher Publisher { get; set; }
    }

    internal class Author{
        public string Name { get; set; }
        public int Age { get; set; }
    }

    internal class Publisher {
        public string Name { get; set; }
    }
        
	//accessing the properties
	var book = new Book();

	var bookName = book.Name ?? "--empty--";  

	WriteLine(bookName);  
	WriteLine($"Name: {book.Name}");
	WriteLine($"Pages: {book.Pages}");
	WriteLine($"Publisher's name: {book.Publisher?.Name}");
	WriteLine($"Authors count: {book.Authors?.Length}");
	WriteLine($"First Author's Name: {book.Authors?[0].Name}");
	WriteLine($"First Author's Age: {book.Authors?[0].Age}");	

We have the concept of null-coalescing operator either, to act in an easier way if some property is null.

        
var bookName = book.Name ?? "--empty--";  

Expression Bodied

The expression bodied are used to simplify the syntax for simpler implementations. It can work either with methods or properties. This approach has some similarity with arrow-functions of Javascript, released on the same year, 2015. 

        
    internal class Car {
        public string Brand { get; set; }
        public int Year { get; set; }
        private string DescriptionComplete => $"{Brand} {Year}";

        public void PrintDescriptionComplete() => WriteLine(DescriptionComplete);
        public string ReturnDescriptionComplete() => DescriptionComplete;
    }
        
	var car = new Car();

	car.PrintDescriptionComplete();
	WriteLine(car.ReturnDescriptionComplete());	

String Interpolation

Now, though string interpolation, it's possible to add objects and expressions as part of the string, in form of concatenation, formatting, manipulation.  

        
	public static void ExecuteExample()
	{
		var author = "John Nash";
		var salary = 32.246423;

		WriteLine($"The author is: {author}. His age is: {calculateAge()}");
		WriteLine($"The salary average is {salary:F2}");
	}

	internal static int calculateAge() => 26;

Exception Filters

Exception filters are clauses that determine when a given catch clause should be applied. It's coming originally from VB and F#.

        
    internal class Test{
        public int Property { get; set; }
    }
        
	Test test = null;

	try {

		var x = test.Property;

	}
	catch (Exception e) when (e.Message.Contains("Object reference")) {
		Console.WriteLine("You can use NullReferenceException, but it's just an example");
	}

NameOf Expression

With nameof expression, it's possible to get in an easy way a name of a variable, property, member field.

        
    internal class Category {
        private string Name { get; set; }

        public Category(string name)
        {
            //using nameof
            Name = name ?? throw new NullReferenceException(nameof(name));
        }
    }


Await Catch Finally

With this new kind of using clause, it's possible to import static members into scope.

        
    public static class Logger {
        public static async Task Error(string message){}
        public static async Task Info(string message){}
    }

    internal class Test2{
        public int Property { get; set; }
    } 
        
	Test2 test = null;

	try 
	{	        
		var x = test.Property;
	}
	catch (Exception)
	{
		await Logger.Error("exception logging");
	}
	finally
	{
		await Logger.Info("finish execution");
	}


Initializes Collection Indexes

With this approach, it's possible to create and access a collection in an easier way, by index.

        
	//first way: compiles generating a call to Add for each of the pairs of int/Product2 values
	var products = new Dictionary(){
		{ 1, new Product2 { Name = "Product 1" }},
		{ 2, new Product2 { Name = "Product 2" }},
		{ 3, new Product2 { Name = "Product 3" }}
	};

	//second way: public read/write indexer method of Dictionary class
	var products2 = new Dictionary(){
		[1] = new Product2 { Name = "Product 1" },
		[2] = new Product2 { Name = "Product 2" },
		[3] = new Product2 { Name = "Product 3" }
	};



---------------------------------------

I hope you have enjoyed this journey until now. Have a nice week!

Here is the entire list of this series:


 


Fabio Ono

No comments:

Post a Comment