A Quick Review of C# 6.0


nameof

When we rename an identifier and the identifier name is referenced in a string then the effect of renaming won’t affect the string.

static void setUser(User user)
{
    if (user == null)
    {
        throw new ArgumentNullException("user", "User is null");
    }
}

Renaming user (#3) will not affect the string "user" (#5)

To resolve this issue, we can use nameof

static void setUser(User user)
{
    if (user == null)
    {
        throw new ArgumentNullException(nameof(user), "User is null");
    }
}

Type safety will be imposed if we use nameof

String interpolation

Old way

const string city = "Dhaka";
const string area = "Dhanmondi";
const string country = "Bangladesh";

var displayAddress = string.Format("Address: {0}, {1}, {2}", area, city, country);

New way

const string city = "Dhaka";
const string area = "Dhanmondi";
const string country = "Bangladesh";

var displayAddress = $"Address: {area}, {city}, {country}";

Another example

var formattedString = $"Today: {DateTime.Now.ToLongDateString()}\n" +
                      $"Dollar: {5:C}";

Console.WriteLine(formattedString);

/*
Today: Sunday, October 16, 2016
Dollar: $5.00
*/

Null conditional operator

Old way

int? age = (user == null) ? (int?) null : user.Age;

// This will crash if user == null
Console.WriteLine($"Name: {user.Fullname}");

New way

int? age2 = user?.Age;

// prints blank if user == null
Console.WriteLine($"Name: {user?.Fullname}");

// default value
int? age3 = user?.Age ?? 0;

// You can chain null checking
Console.WriteLine($"Length: {user?.Fullname?.Length}");

Index initializer

Old way

var dict = new Dictionary<string, string>()
{
    { "Name", "John Doe" },
    { "Profession", "Soft Engg."}
};

New way

var newDict = new Dictionary<string, string>()
{
    ["Name"] = "New John Doe",
    ["Profession"] = "New Soft Engg."
};

Method extension

Suppose we have a class called UserDB

using System.Collections;
using System.Collections.Generic;

namespace AQuickReviewCSharp6
{
    public class UserDB : IEnumerable<User>
    {
        List<User> users = new List<User>();

        public IEnumerator<User> GetEnumerator()
        {
            return users.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public User Insert(User anUser)
        {
            users.Add(anUser);
            return anUser;
        }
    }
}

Notice that, there is no Add method. Now, if we would like to make an UserDB object and use index initializer then we will get error.

var userCollection = new UserDB()
{
    new User { Fullname = "User 01", Age = 25 },
    new User() { Fullname = "User 02", Age = 30 }
};

Cannot resolve symbol 'Add'

To resolve this we can use extension and add a new method named Add

static class UserDBExtension
{
    public static User Add(this UserDB db, User anUser)
    {
        db.Insert(anUser);
        return anUser;
    }
}

await in catch and finally block

private static async void AMethod()
{
    try
    {
        throw new Exception("Error");
    }
    catch (Exception ex)
    {
        await log("Catch: ", ex);
    }
    finally
    {
        await log("Finally: ", null);
    }
}

private static async Task log(String log, Exception ex)
{
    using (var file = File.AppendText("app.log"))
    {
        await file.WriteLineAsync($"{log} {ex?.ToString()}");
    }
}

Exception filter

You can add exception filter, pretty much like if-else if-else

try
{
    throw new Exception("Error");
}
catch (Exception ex) when (ex.Message.Contains("Warning"))
{
    // Just an warning
}
catch (Exception ex)
{
    // Handle exception
}
finally
{
    Console.WriteLine("Finally");
}

Remember: You need to return a boolean (true) if you handled the case, so that further catch clauses will not be executed.

Auto property initializer

We can initialize a property without using constructor.

public class User
{
    public string Fullname { get; set; } = "Great user";
    public int Age { get; set; } = 20;
}

This is also applicable for getter only properties

public class User
{
    public string Fullname { get; set; } = "Great user";
    public int Age { get; set; } = 20;
    public string Country { get; } = "Australia";
}

Few short hand techniques

Old way

static private string name = "John Doe";

static public string Name
{
    get { return name; }
}

New way

static public string Name = "John Doe";

Old way

static public string GetFullName(string firstName, string lastName)
{
    return String.Format("{0} {1}", firstName, lastName);
}

New way

static public string GetFullName(string firstName, string lastName) => $"{firstName} {lastName}";

Old way

static public User GetUser(string firstName, string lastName)
{
    return new User(firstName, lastName);
}

New way

static public User GetUser(string firstName, string lastName) => new User(firstName, lastName);

static using

using System;
using static System.Console;

public static void Main(string[] args)
{
    WriteLine("Hello World");
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s