developmentcsharp

There are 2 improvements on exception handling:

  1. Exception filters
  2. Using await in catch and finally blocks

Exception Filters

Visual Basic and F# already have this feature and now C# has it too! the way it works is basically defining a condition for the catch block (example taken from Channel 9 video):

try
{

}
catch(ConfigurationException e) if (e.IsSevere)
{

}

I think it can make exception handling more modular. Also it’s better than catching and rethrowing in terms of we don’t lose information about the original exception.

Using await in catch and finally blocks

Like most people I hadn’t noticed we couldn’t do that already! Apparently it was just a flaw in the current implementation and they closed that gap with this version

try
{

}
catch(ConfigurationException e) if (e.IsSevere)
{
	await LogAsync(e);
}
finally
{
	await CloseAsync();
}

developmentcsharp

Personally I think this one is a bit trivial. So the argument is it eliminates the need for using hard-coded strings in the code.

For instance:

public class NameofOperator
{
    public void Run(SomeClass someClass)
    {
        if (someClass == null)
        {
            throw new ArgumentNullException("someClass");
        }
    }
}

public class SomeClass
{
}

Say you refactored the code and changed the parameter name in this example. It is likely to forget changing the name in the exception throwing line since it has no reference to the actual parameter.

By using nameof operator we can avoid such mistakes:

public class NameofOperator
{
    public void Run(SomeClass refactoredName)
    {
        if (refactoredName == null)
        {
            throw new ArgumentNullException(nameof(refactoredName));
        }
    }
}

public class SomeClass
{
}

The results are identical but this way when we change a parameter name all references to that object will be updated automatically.

developmentcsharp

This is another handy feature. Checking for null values before accessing them can quickly become cumbersome and yields a lot of boilerplate code. With this new operator checking for nulls and coalescing becomes really short and easy to read.

For example:

public class NullConditionalOperators
{
    public void Run()
    {
        Person person = GetPerson();

        // Current C#
        if (person != null && person.Country != null)
        {
            Console.WriteLine(person.Country.Name);
        }
        else
        {
            Console.WriteLine("Undefined");
        }
    }

    private Person GetPerson()
    {
        return new Person() { Firstname = "Volkan", Lastname = "Paksoy" };
    }
}

public class Person
{
    public string Firstname { get; set; } = "Unknown";
    public string Lastname { get; set; } = "Unknown";
    public Country Country { get; set; }
    
}

public class Country
{
    public string Name { get; set; }
    public string IsoCode { get; set; }
}

In the example above if you need to print the name of the country first you need to ensure both the Person and Country objects are not null. The if block aobe can be reduced to a one-liner with 6.0:

	Console.WriteLine(person?.Country?.Name ?? "Undefined");

They both produce the same results. The more complex the object hierarchy becomes the more useful this feature would be.