NameOf (C# 6)

Submitted by Robert MacLean on Tue, 04/14/2015 - 13:40
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

nameof is a fantastic piece of syntactic sugar in C# 6, which aims to solve a major pain: magic strings. A magic string is a type of string in your application which is isn’t an input/output related but rather a marker or used for some comparison, for example you might do role checking with something that looks like this:

if (role == "admin")
{
}

The issue with this string “admin”, is that there is NO compiler checking for it. That means if you mistype the content of the string, you do not know it is wrong until the app fails. The second issue with a magic string, is that the refactoring tools do not commonly work with them, so if you changed “admin” to “administrator” in one place, there is no way to tools can find and update all the strings throughout you app and your app breaks again when it runs.

A lot of time you can clean this up with enumerators or objects. For example we can improve our role scenario but checking against an enumerator:

if (role == Roles.admin.ToString())
{
}

This no longer suffers from the two issues listed above Smile

Members & Magic Strings

The problem remains with magic strings which refer to members (fields, properties, methods, types etc…) of your code. In this first example we have a magic string pointing to the property Age:

public int Age
{
    get { return age; }
    set
    {
        age = value;
        RaisePropertyChanged("Age");
    }
}

For the second example we have a magic string  pointing to a class Track:

var type = Type.GetType("Track");

And finally our third example is around checking a field for null and raising an exception, if needed, with the correct field name:

private void RaisePropertyChanged(string propertyChanged)
{
    if (propertyChanged == null)
    {
        throw new ArgumentNullException("propertyChanged");
    }

    // do stuff
}

All of these examples suffer from the same two problems listed with magic strings, but until now, there hasn’t been a way to effectively clean them up.

nameof

The goal of the new nameof keyword is to solve this specific type of magic string, i.e. ones which refer to members in code. By using nameof we can change the above examples to the following:

// example 1
public int Age
{
    get { return age; }
    set
    {
        age = value;
        RaisePropertyChanged(nameof(Age));
    }
}

// example 2
var type = Type.GetType(nameof(Track));

// example 3
private void RaisePropertyChanged(string propertyChanged)
{
    if (propertyChanged == null)
    {
        throw new ArgumentNullException(nameof(propertyChanged));
    }

    // do stuff
}

Note we have eliminated the strings completely! This means if you mistype a member name at compile time you would get an error!

image

We also get FULL refactoring support now, since Visual Studio and other refactoring tools can get the information they need to identify that it is a member and replace/rename as needed.

More sugar

As mentioned at the start, this is just a case of syntactic sugar, the compiler is doing clever tricks for us and generating slightly different code. All nameof does, is instruct the compiler to convert the member to a string, so the outputted code is the same before with strings.

I want to recommend the TryRosyln website which is FANTASTIC to experiment with C# 6 and also shows you the decompiled code side by side, basically showing you how the syntactic sugar works:

image

What does it output?

In the first set of examples we looked at simple members, but what if we have something more complex for example a namespace or a class & property. In these cases it will output the last part each time:

nameof(Track.Band); // Class.Property - outputs: Property, in this case 'Band'
nameof(System.Configuration); // Namespace - outputs: Last namespace, in this case 'Configuration'
nameof(List); // List + Generics: outputs: The type of the object, in this case 'List' <
nameof(this.field); // this keyword + field - outputs the field name 'field'

What isn’t supported

nameof isn’t a solution to everything in .NET and there is a lot which won’t work. Here are some examples:

nameof(f()); // where f is a method - you could use nameof(f) instead
nameof(c._Age); // where c is a different class and _Age is private. Nameof can't break accessor rules.
nameof(List<>); // List<> isn't valid C# anyway, so this won't work
nameof(default(List<int>)); // default returns an instance, not a member
nameof(int); // int is a keyword, not a member- you could do nameof(Int32)
nameof(x[2]); // returns an instance using an indexer, so not a member
nameof("hello"); // a string isn't a member
nameof(1+2); // an int isn't a member

Is this a replacement for CallerMemberName?

I have written about a fantastic .NET 4.5 feature called CallerMemberName. To recap it is a way to attribute a parameter of a method and have the runtime change the value of that parameter to be the name of the calling member. In the following example the output will be ‘Main’, matching the name of the calling method:

private static void Main(string[] args)
{
    WhoCallsMe(); 
}

static void WhoCallsMe([CallerMemberName] string caller = "")
{
    Console.WriteLine(caller);
}
This seems to be similar to nameof but there are some fundamental differences, most importantly nameof is at COMPILE TIME and CallerMemberName is at RUNTIME. This means that this one method in the example can work with multiple callers; i.e. I could take the above example and have a different member call it and it will output the correct name of the caller. There is no way to do that with nameof, which is basically hard coded values. There is some overlap of functionality and in some cases, like XAML + RaisePropertyChanged where you could pick one or the other based on taste, but these two pieces of functionality do have their differences and there are times where CallerMemberName is the really only option.

The null propagation operator - NULLET (C# 6)

Submitted by Robert MacLean on Tue, 04/14/2015 - 09:03
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

NULLs, you either hate them or you loath them. They are the source of so many issues in the apps we write, especially the dreaded NullReferenceException. The current fix is to be very defensive in your programming, for example:

public static void Exception(Track track)
{
    // this may cause an exception if the track object, band property or the frontman property is null
    Console.WriteLine("HI! " + track.Band.FrontMan.Name);

    // defensive programming to avoid null exceptions
    if (track != null && track.Band != null && track.Band.FrontMan != null)
    {
        Console.WriteLine("HI! " + track.Band.FrontMan.Name);
    }
}

Constant null checking also makes working with events particularly ugly, because you need to check for nulls before you call an event:

internal class NullConditionalEvent : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePain(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

NULLET

Clipboard01With C# 6, a new operator has been added; which is officially called the null propagation operator: ?.

Some people have taken to calling it the Elvis operator as it looks like two eyes & a splash of hair similar to Elvis, however I think that hair looks a lot more like a mullet so I have taken to calling this the NULLET operator.

The nullet operator allows us to check for nulls, so we can change the first example to the following which will NOT raise a a null exception:

public static void Exception(Track track)
{
    Console.WriteLine("HI! " + track?.Band?.FrontMan?.Name);
}

The way the nullet works, is that it tells .NET to check if the preceding item is null BEFORE moving to the next item. If the item is null, then it stops evaluation at that point and returns null, for example with track:

image

If you want the internals of this logic, check out this amazing post on Roslyn Codeplex site.

The important question is what will be the outcome of our above example; if any of the properties are null then it will be “HI!” + NULL which becomes “HI! “ and so that is what will be written to the screen.

Events & Methods

In the first example, there is an example of events and how you need to check for null before raising it. A side note is I am using events as the example, but this applies to any delegate. In the following example you can see how the nullet can help us clean up the event code:

private void RaisePain(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

To be able to call the event we need something for the nullet to do after the evaluation, so we use the invoke method. This is also a great example of how the nullet is more than just support properties, it works with methods too.

Null + Indexers = Support for arrays & lists

Nullet can work indexers as well, with a small syntax change – instead of ?., you have just ? (i.e. just a question mark, no trailing full stop). In both scenarios below the code happily executes with NO null issues because we have added the ? between the object and the indexer.

Track[] album1 = null;
Console.WriteLine("Album 1 Track 6 " + album1?[5]);

List<Track> album2 = null;
Console.WriteLine("Album 2 Track 3 " + album2?[4]);

Not the end of all your null pain

The key fact around nullet is that it is a short hand in your code which prevents NullReferenceException but you can still have exceptions related to NULL. An example of this when you use Enum.Parse:

Enum.Parse(typeof(Example), track?.Band?.FrontMan?.PrimaryInstrument);

In this scenario, if you have any section as null, it will return a null, however the  Enum.Parse method cannot handle null and will raise a NullArgumentException. In this case the method you are passing the null too is key, so you still need to make sure you are checking for nulls in some scenarios, but you can use nullet to make the checking much cleaner:

if (!string.IsNullOrWhiteSpace(track?.Band?.FrontMan?.PrimaryInstrument))
{
    Enum.Parse(typeof(Example), track?.Band?.FrontMan?.PrimaryInstrument);
}

Exception Filtering (C# 6)

Submitted by Robert MacLean on Fri, 04/10/2015 - 08:27
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

Many of the other C# 6 features I’ve covered are implemented using syntactic sugar, exception filters isn’t. This has been in the deep parts of .NET for some time and in C# 6 it is getting surfaced finally. This is very much the introduction to Exception Filtering, and I have another post with advanced topics I would love for you to read.

Catching Exceptions

Catching exceptions today uses the exceptions type as the condition for the the catch block.

try
{
    // code which could throw exception
}
catch (HttpException ex)
{
   // catching only HttpExceptions
}

In the above code, any HttpException will be caught but any exception of any other type won’t.

try
{
    // code which could throw exception
}
catch (HttpException ex)
{
   // catching only HttpExceptions
}
catch (Exception ex)
{
    // catching everything except HttpExceptions
}

We can catch everything by catching the base Exception class. Order here matters, but the compiler will help prevent you from hurting yourself:

image

Today, if you want more fine grain control of what a catch block responds to you need to do that in the catch block itself.  For example, handling an exception differently based on values in the exception.

try
{
    // some code
}
catch (HttpException ex)
{
    if (ex.HttpCode == 401)
    {
        // need to do an authenticate
    }
    else
    {
        // some other HTTP error we need to handle
    }
}

Another good example is logging, based on a setting you may want to log or not log exceptions.

try
{
    // some code
}
catch (HttpException ex)
{
    if (loggingTurnedOn)
    {
        // log it
    }

    throw;
}

Exception Filters

Exception Filters adds a way to have additional requirements for a catch block in the form of a boolean expression which we append with the when keyword. We can now rewrite the two examples as follows:

//example 1
try
{
    // some code
}
catch (HttpException ex)
    when (ex.HttpCode == 401)
{
    // need to do an authenticate
}
catch (HttpException ex)
{
    // some other HTTP error we need to handle
}

//example 2
var loggingTurnedOn = false;
try
{
    // some code
}
catch (HttpException ex)
    when (loggingTurnedOn)
{
    // log it               
    throw;
}

The when clause can take in ANYTHING which evaluates to a boolean expression. You can put ands or ors and chain things together:

when (loggingTurnedOn && ex.HttpCode != 401)

You can pass methods in to the when condition too:

public static bool ThrowException()
{
    //elided
}

public static void OldPain2()
{  
    try
    {
        // some code
    }
    catch (HttpException ex)
        when (ThrowException())
    {
       // do something
    }
}

When isn’t if

Lastly, the language chosen for this feature is important, it isn’t IF, because it isn’t an IF statement – it is a WHEN condition. One of the important distinctions around that is that an IF statement supports ELSE and WHEN does not.

Static Using Statements (C# 6)

Submitted by Robert MacLean on Wed, 04/01/2015 - 07:54
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

Static using statements are a new feature of C# 6 designed to improve the readability of code. Before we begin: a word of warning for this feature. IMHO This feature is not meant to be used everywhere in your code. This feature is like salt, a little is great – too much, can cause issues.

With the warning out of the way, lets see what it does? There are times where the class name can break the flow of the code, lowering readability. Here is some example code we will work with:

using System;

internal class StaticUsing
{
    private void BrokenFlow()
    {
        Console.WriteLine(Math.Cos(5) * Math.Tan(20) + Math.PI);
    }
}

The addition of the Math class makes this a little harder to read, so we can use the new static using statement feature to remove that:

using System;
using static System.Math;

internal class StaticUsing
{
    private void BrokenFlow()
    {
        Console.WriteLine(Cos(5) * Tan(20) + PI);
    }
}

Note, that while we have removed the Math class from line 8, we have added a new using statement with the static keyword in line 2. This line tells the compiler where to look if it cannot find the method/property in the current scope. This is just syntactic sugar again and the resulting code is the same as in the first example.

The only requirement for this to work is that the class is that the class is static. That means this works with Math, Console, Convert & any of YOUR own static classes too.

What happens if I have a member with the same name already in scope?

What happens if there is already a member in scope with the same name, for example here I have defined a Cos method:

public static void BrokenFlow()
{
    Console.WriteLine(Cos(5) * Tan(20) + PI);
}

public static double Cos(int value)
{
    return -1;
}

In this scenario it uses the locally defined member first, as that is the first one which the compiler finds. This is an example of where you can shoot yourself in the foot by using this feature too often and running into hard to find conflicts.

What about Extension Methods?

C# 3.0 added support for extension methods which let you write methods which appear to be part of the underlying class but are actually separate. I’ve added the example method to the string class in the following example:

namespace ConsoleApplication1
{
    using System;
    using ExtensionMethods;

    internal class StaticUsing
    {
        public static void BrokenFlow()
        {
            Console.WriteLine("Robert".Example());
        }
    }
}

namespace ExtensionMethods
{
    public static class Extensions
    {
        public static string Example(this string s)
        {
            return "Hello " + s;
        }
    }
}

Adding the static using statement still allows extension methods to be used as normal, however you cannot call the extension method directly this way. If you want to call the extension method directly, you must add the class (& potentially the namespace) in front of the method as you do with C# 5 and before.

using System;
using static ExtensionMethods.Extensions;

internal class StaticUsing
{
    public static void BrokenFlow()
    {
        Console.WriteLine(ExtensionMethods.Extensions.Example("Leslie")); // this works
        Console.WriteLine(Example("Robert")); // this does NOT work
        Console.WriteLine("Robert".Example()); // this works
    }
}

Read-only auto-properties (C# 6)

Submitted by Robert MacLean on Tue, 03/31/2015 - 07:59
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

Continuing on from the previous post with auto-property initialisers, the second enhancement to auto-properties in C# 6 is proper support for read-only properties.

Before we get to the C# 6 solution, let us look at C# 1 and how we have done this in the past. In C# 1 we can remove the setter of a property to have a property which is read-only:

private int csharpOne = 42;

public int CSharpOne
{
    get { return csharpOne; }
}

With C# 2 auto-properties we did not get support for a read-only version. The closest we could get to the same functionality is limit the accessibility of the setter, for example:

   public int CSharpTwo { get; private set; }

Finally with C# 6 we get true read-only support in auto-properties, which allows us to assign the value using either the new auto-property initialiser syntax or in the constructor. For example:

public int CSharpSix { get; } = 42;

The changes to auto-properties really will have a lot of benefits for cleaner code. What do you think?

Auto-properties with initializers (C# 6)

Submitted by Robert MacLean on Mon, 03/30/2015 - 15:59
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

A big design trend in C# 6 is the removal of ceremony from code. Ceremony is the amount of code you need to write, to write the code that actually matters. It is the fluff that is there because it is needed by C# and not to solve your problem. Auto-properties are a great example of removal of ceremony & in C# 6 they have been improved further.

In C# 1 we would would type out the full property with the getter & setter and a field. One nice feature is you could initialise the value the field, thus giving the property a default value. For example, like this:

private int csharpOne = 42;

public int CSharpOne
{
    get { return csharpOne; }
    set { csharpOne = value; }
}

In C# 2 we got the (syntactic sugar) feature for one line properties. The compiler though would generate the field, the getter and the setter automatically in the compiled code. However, the loss of the field, meant the only way to assign a default value was in the constructor, as in the following example:

public int CSharpTwo { get; set; }

public AutoProperties()
{
    CSharpTwo = 42;
}

On one hand, the single line property is great and is an example of less ceremony adding readability, but when we need to assign a default value we add more ceremony and ultimately increase complexity and the potential for errors because there is no obvious way to see the constructor is assigning a value unless you go and check it.

C# 6 simplifies solves this with a new syntax to assign a default value:

public int CSharpSix { get; set; } = 42;

That is pretty awesome!

Exceptions: What happens when an exception occurs inside a catch or inside a when (C# 6) & how smart is the compiler with whens which have a constant expressions or whens with duplicate expressions?

Submitted by Robert MacLean on Sun, 03/29/2015 - 15:34
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

Exceptions, the bit of code that makes everything break! Here are some interesting thoughts around how exceptions work, which were brought up during a recent presentation I gave on C# 6.

Note: Based on VS 2015 CTP 6, this may change by RTM.

Exceptions in a catch block

Starting off, let us look at what happens if you raise an exception in the catch block of a try…catch? This isn’t anything new to C# 6, but it is worth a recap.

public static void OldPain()
{
    try
    {
        throw new MyException { Id = 200 };
    }
    catch (MyException ex)
    {
        throw new Exception("WHAT");
    }
}
In this scenario, the first exception (MyException) is caught and then the second exception is raised. Since there is no try…catch for the second exception, it runs normally and bubbled up until it is either caught higher up or the app crashes. In this example that means an exception of type Exception will be raised.

What if we add a catch all?

As a slight variation, what happens if you add another catch below the first one? Does the second catch, catch the exception raised in the first catch block? For example:

public static void OldPain()
{
    try
    {
        throw new MyException { Id = 200 };
    }
    catch (MyException ex)
    {
        throw new Exception("WHAT");
    }
    catch (Exception ex)
    {
        // stuff
    }
}

Nope, not at all. It exits the entire try…catch scope and, so that second catch does nothing for what we are testing. In the example above, that means an exception of type Exception will be raised, same as with the first scenario.

Exceptions in When

C# 6 adds the when keyword which allows us to add a filter to our catch blocks. This feature is called Exception Filters & you may find articles using IF as the keyword, but that has changed to WHEN. Prior to C# 6, the condition to run a catch block was just the exception type. Now with C# 6, it is the exception type and, optionally, the result of the when expression. So what happens if the when expression raises an exception? For example:

public static bool Test()
{
    throw new Exception("WHAT!");
}

public static void OldPain()
{
    try
    {
        throw new MyException { Id = 200 };
    }
    catch (MyException ex)
    when (Test())
    {
    }
}

I assumed it would work in a similar way to the exceptions inside the catch block we looked at above. I was wrong. Any exception in the when condition is swallowed up! In this example, the MyException will be raised since there is no catch block which can handle it as the when has failed due to the exception being raised in test.

What if we add a catch all?

As with the first example, does adding a second catch…block here change the behaviour?

public static bool Test()
{
    throw new ApplicationException("WHAT!");
}

public static void OldPain()
{
    try
    {
        throw new MyException { Id = 200 };
    }
    catch (MyException ex)
    when (Test())
    {
    }
    catch (ApplicationException ex)
    {
        // will this be run?
    }
}

No, this scenario runs the same as before, a MyException is raised.

Constant Whens

What happens if the when expression is a constant? Is the compiler smart enough to optimise the code? To work this out I used the AMAZING .NET Reflector which means I can compare the original code, the IL which was generated and the code which was reflected back from the IL.

Starting off with the standard filter, here is what it  looks like across places. I suspect the reflected code is showing ? since the version of reflector out currently doesn’t support this.

image

Let us change the condition to be always true. Thankfully Visual Studio will detect this and warn you:

image

But what is the result of compiler?

image

It is pretty much the exact same there, with the filter existing in the IL still :/ Checking with false (and also release builds) shows no difference in any scenario :/

Duplicate whens

The last set of scenarios are around for duplicate when clauses, for example below we have two catch blocks which are the same and I know from running this that only the first one is executed.

public static void OldPain()
{
    try
    {
        throw new MyException { Id = 200 };
    }
    catch (MyException ex)
    when (ex.Id == 200)
    {
    }
    catch (MyException ex)
    when (ex.Id == 200)
    {
    }
}

And from checking the generated IL, both catches are in there too. So no optimisation around this.

As a final mad scientist idea, what if the first catch changes the condition to one the second catch can handle? Will that allow both to run? For example:

public static void OldPain()
{
    var canCatch = true;
    try
    {
        throw new MyException { Id = 200 };
    }
    catch (MyException ex)
    when (canCatch)
    {
                canCatch = false;
    }
    catch (MyException ex)
    when (!canCatch)
    {
    }
}

The answer, is nope. Once one catch handles it the rest are ignored.

I hope you find this new syntax interesting and if you have any questions, please post them in the comments!

Index Initialisers (C# 6)

Submitted by Robert MacLean on Sun, 03/29/2015 - 15:26
C# 6
Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub

C# 6 adds in a new feature which is called Dictionary Initialisers or Index Initialisers, because of how they work internally.  In fact, the C# team can’t get it straight with roadmap page referring to dictionary while the feature description document, referring to index. While we wait for the name to be decided, what is an index initialiser and how does it work internally?

Note: This is based on VS 2015 CTP 6 and thus may change.

Adding to collections in C# 2

In C# 2 the only way we could add to a collection was with the methods provided by the collection, normally add. For example, below we are adding to a dictionary and an list using the C# 2 way.

public static void CSharp_Two_Dictionary()
{
    var config = new Dictionary<int, string>();
    config.Add(1, "hi");
    config.Add(2, "how are you");
    config.Add(3, "i am fine");
    config.Add(4, "good bye");
    foreach (var item in config)
    {
        Console.WriteLine("{0} = {1}", item.Key, item.Value);
    }
}

public static void CSharp_Two_List()
{
    var config = new List<string>();
    config.Add("hi");
    config.Add("how are you");
    config.Add("i am fine");
    config.Add("good bye");
    foreach (var item in config)
    {
        Console.WriteLine(item);
    }
}

Collection Initialisers in C# 3

C# 3 added support for collection initialisers, where we can use braces to add the items. When using collection initialisers, the parentheses for the constructor become optional - for the example below I have omitted them.

This is just syntactic sugar, i.e. the compiler is rewriting this to use the Add method of the collection. In short it ends up the same as the example above when it is run - it is just easier and less error prone to type using collection initialisers.

The requirements collection initialisers to work are::

  1. The collection class must implement IEnumerable.
  2. The collection class must have an add method. Almost uniquely for .NET there is no interface required, it is merely the name of the method and that it must take, at least, one parameter.
public static void CSharp_Three_Dictionary()
{
    var config = new Dictionary<int, string>
    {
        { 1, "hi" },
        { 2, "how are you" },
        { 3, "i am fine" },
        { 4, "good bye" },
    };

    foreach (var item in config)
    {
        Console.WriteLine("{0} = {1}", item.Key, item.Value);
    }
}

public static void CSharp_Three_List()
{
    var config = new List<string>
    {
        "hi",
        "how are you",
        "i am fine",
        "good bye",
    };

    foreach (var item in config)
    {
        Console.WriteLine(item);
    }
}

Index Initialisers in C# 6

C# 6 adds a new syntax option to add items to collections, where we can add items to collections in a slightly different way:

public static void CSharp_Six_Dictionary()
{
    var config = new Dictionary<int, string>
    {
        [1] = "hi",
        [2] = "how are you",
        [3] = "i am fine",
        [4] = "good bye",
    };

    foreach (var item in config)
    {
        Console.WriteLine("{0} = {1}", item.Key, item.Value);
    }
}

public static void CSharp_Six_List()
{
    // note: this will error
    var config = new List<string>
    {
        [1] = "hi",
        [2] = "how are you",
        [3] = "i am fine",
        [4] = "good bye",
    };

    foreach (var item in config)
    {
        Console.WriteLine(item);
    }
}

In the above example you’ll note that we use similar syntax to the collection initialiser (use of brace, optional use of constructor parenthesis) but the way we add items is different. We use brackets to define the index, followed by equals and the value. Internally this is different to collection initialisers since the generated code does NOT use the add method, rather it uses the collections indexer. For example, this is what the generated code the above index initialiser example would look like:

public static void CSharp_Six_Dictionary_Generated()
{
    var config = new Dictionary<int, string>();
    config[1] = "hi";
    config[2] = "how are you";
    config[3] = "i am fine";
    config[4] = "good bye";

    foreach (var item in config)
    {
        Console.WriteLine("{0} = {1}", item.Key, item.Value);
    }
}

public static void CSharp_Six_List_Generated()
{
    // note: this will error
    var config = new List<string>();
    config[1] = "hi";
    config[2] = "how are you";
    config[3] = "i am fine";
    config[4] = "good bye";

    foreach (var item in config)
    {
        Console.WriteLine(item);
    }
}

Since the compiler is generating code with indexers, the ONLY requirement for the class being added is that the class it must have an indexer and the indexer has which has a setter method. This means it can be used on anything which supports indexers. There is NO requirement that this can only be used with collections or things which support IEnumerable.

In the above example the List example will fail and the Dictionary will pass because of the subtle differences in how their indexers work. A dictionary uses the setter on the indexer as the key and will add the item if needed, while a list uses the setter on its indexer as a position and if the list doesn’t have a collection with that size it will fail with an exception.

Example non-collection usage

As mentioned this can be used outside a collection, so let us build a bit of code to assign the four roles to a team.

NOTE: This is an example, it is not meant as guidance for how you should do it. Personally, I think the end example is better handled by a constructor.

In C# 2 we may have done it like this:

public static void C_Sharp_Two_Set_Members()
{
  // code to add team members
    var team = new Team();
    team.ScrumMaster = new Member("Jim");
    team.ProjectOwner = new Member("Sam");
    team.DevLead = new Member("Phil");
    team.Dev = new Member("Scott");
}

// we will exclude role from future examples since it doesn't change in the other examples
enum Role
{
    ScrumMaster,
    ProjectOwner,
    DevLead,
    Dev
}

class Team
{
    public Member ScrumMaster { get; set; }
    public Member ProjectOwner { get; set; }
    public Member DevLead { get; set; }
    public Member Dev { get; set; }
}
// we will exclude member from future examples since it doesn’t change in the other examples
class Member
{
    public Member(string name)
    {
        Name = name;
    }

    
    public string Name { get; }
}

With C# 3 we could change this to use an object initialiser, which ultimately generates the exact same code as in C# 2:

// rest of example code remains the same
public static void C_Sharp_Three_Object_Initialiser()
{
    var team = new Team
    {
        ScrumMaster = new Member("Jim"),
        ProjectOwner = new Member("Sam"),
        DevLead = new Member("Phil"),
        Dev = new Member("Scott"),
    };
}

The one requirement for both examples is that the properties have accessible setter methods, or it will not work, so we cannot use either option with private setters for example. We could use an indexer in this scenario by adding it to the Team class and then being able to use Index initialiser syntax to assign the roles.

public static void C_Sharp_Six_Index_Initialiser()
{
    var team = new Team
    {
        [Role.ScrumMaster] = new Member("Jim"),
        [Role.ProjectOwner] = new Member("Sam"),
        [Role.DevLead] = new Member("Phil"),
        [Role.Dev] = new Member("Scott"),
    };
}


class Team
{
    public Member this[Role role]
    {
        get
        {
            switch (role)
            {
                case Role.ScrumMaster:
                    return this.ScrumMaster;
                case Role.ProjectOwner:
                    return this.ProjectOwner;
                case Role.DevLead:
                    return this.DevLead;
                case Role.Dev:
                    return this.Dev;
            }

            throw new IndexOutOfRangeException();
        }
        set
        {
            switch (role)
            {
                case Role.ScrumMaster:
                    {
                        this.ScrumMaster = value;
                        break;
                    }
                case Role.ProjectOwner:
                    {
                        this.ProjectOwner = value;
                        break;
                    }
                case Role.DevLead:
                    {
                        this.DevLead = value;
                        break;
                    }
                case Role.Dev:
                    {
                        this.Dev = value;
                        break;
                    }
            }
        }
    }
    public Member ScrumMaster { get; private set; }
    public Member ProjectOwner { get; private set; }
    public Member DevLead { get; private set; }
    public Member Dev { get; private set; }
}

Hopefully this explains the new syntax in C# 6 and gives you good ideas on where and how it works. If you have any ideas of how Index Initialisers could be used, let me know in the comments below!

Slides from my DevDay (March 2015) talks!

Submitted by Robert MacLean on Fri, 03/20/2015 - 09:07

First off, let me thank everyone who attended – this was one of the best events I’ve been involved in and that is all down to the great audiences we had. Not only was it fun and exciting but I learnt so much from all of you around the various pieces of technology you use and frustrations of it.

Sharp Sharp with C# 6

This is one of my favourite talks I’ve ever given. I don’t think I have ever laughed as much on stage as I did with this talk.

You can find the starting code for this on GitHub

Putting the “DOT” into .NET – Dev, Ops & Test

For Johannesburg audiences, this will look a lot different. I got so much amazing feedback & ideas that I did a lot of work on polishing and structuring it better and I am very proud of the final outcome. It still is a long talk which covers a lot (too much maybe) but it is one that I think stimulates a lot of ideas & nudges people on a very important path.