.NET 4.6.2 and C# 7 New Features

Content:

  1. Version numbers
  2. Release
  3. General
  4. Literals
  5. Out values
  6. Tuples
  7. Local functions
  8. Pattern matching
  9. Expresssion body
  10. Missing

Version numbers:

.NET framework, .NET runtime, C# language/compiler and Visual Studio IDE each have their own version numbering scheme. For this release they are at 4.6.2, 4.0, 7.0 and 2017 respectively.

.NET framework .NET runtime C# language/compiler Visual Studio IDE Release date
1.0 1.0 1.0 2002 February 13th 2002
1.1 1.1 1.2 2003 April 24th 2003
2.0 2.0 2.0 2005 November 7th 2005
3.5 2.0 3.0 2008 November 19th 2007
4.0 4.0 4.0 2010 April 12th 2010
4.5 4.0 5.0 2012 August 15th 2012
4.5.1 4.0 5.0 2013 October 17th 2013
4.6 4.0 6.0 2015 July 20th 2015
4.6.2 4.0 7.0 2017 March 7th 2017 (framework August 2nd 2016)

Release:

VS 2017 was released March 7th 2017.

General:

The changes to .NET as inidcated by the small version number change are minor, but there are significant changes to C#.

The C# compiler team seems to have been very productive abd have added a bunch of new features inspired by many of the newer FP languages (.NET's own F#, Scala etc.).

Literals

C# 7 allows binary literals and underscore in numbers to make them more readable similar to Java in version 7.

Previous:

using System;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int v1 = 0x03030303;
            Console.WriteLine(v1);
            int v2 = 123456789;
            Console.WriteLine(v2);
        }
    }
}

Now:

using System;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            int v1 = 0b00000011000000110000001100000011;
            Console.WriteLine(v1);
            int v2 = 123_456_789;
            Console.WriteLine(v2);
        }
    }
}

I think it is useful but not really important.

I don't think any of these will be used much.

Out values

C# 7 got a new simpler syntax for declaring out variables. They can now be declared directly in the method call.

Previous:

using System;

namespace E
{
    public class Program
    {
        public static void M(out int v)
        {
            v = 123;
        }
        public static void Main(string[] args)
        {
            int v;
            M(out v);
            Console.WriteLine(v);
        }
    }
}

Now:

using System;

namespace E
{
    public class Program
    {
        public static void M(out int v)
        {
            v = 123;
        }
        public static void Main(string[] args)
        {
            M(out int v);
            Console.WriteLine(v);
        }
    }
}

I don't see much point in doing this. It become rather tricky to spot the declation.

And I don't think it will be used much.

Tuples

C# 7 got tuples. C# has had a reference type Tuple available since .NET 4.0, but this is different. This is value type tuple. And it is supported in the C# language itself not just as a type in the .NET framework.

The syntax for declaring a method returning a tuple is one of:

modifier (type1,...,typen) methodname(...)
modifier (type1 name1,...,typen namen) methodname(...)

The syntax for capturing the return value is one of:

(type1 name1,...,typen namen) = methodname(...); // with values in namei
var resname = methodname(...); // with values in resname.namei
var resname = methodname(...); // with values in resname.Itemi

I will show the combination that I expect to become most popular.

Previous:

using System;

namespace E
{
    public class Program
    {
        public static Tuple<int,int> M()
        {
            return Tuple.Create(123, 456);
        }
        public static void Main(string[] args)
        {
            Tuple<int,int> tmp = M();
            int v1 = tmp.Item1;
            int v2 = tmp.Item2;
            Console.WriteLine($"{v1} {v2}");
        }
    }
}

Now:

using System;

namespace E
{
    public class Program
    {
        public static (int,int) M()
        {
            return (123, 456);
        }
        public static void Main(string[] args)
        {
            (int v1,int v2) = M();
            Console.WriteLine($"{v1} {v2}");
        }
    }
}

If you get weird errors when using this feature then make sure that you have ref to System.ValueTuple.dll (and maybe System.Runtime.dll). I got several different versions of System.ValueTuple.dll when I installed VS2017 - one that seems to work is in C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\PrivateAssemblies.

I think this is a very usefull feature to simplify code.

I think it will take a little time for people to get used to but that it eventually will become quite popular.

Local functions

C# 7 got local functions (methods) aka a named local function (method) inside another method. Similar to how functions/procedures can be nested in Pascal.

Previous:

using System;

namespace E
{
    public class Program
    {
        private static int AddOne(int ini, int v)
        {
            return ini + v;
        }
        public static int AddThree(int acc, int v1, int v2, int v3) 
        {
            return AddOne(AddOne(AddOne(acc, v1), v2), v3);
        }
        public static void Main(string[] args)
        {
            Console.WriteLine(AddThree(0, 123, 456, 789));
        }
    }
}

Now:

using System;

namespace E
{
    public class Program
    {
        public static int AddThree(int acc, int v1, int v2, int v3) 
        {
            int AddOne(int ini, int v)
            {
                return ini + v;
            }
            return AddOne(AddOne(AddOne(acc, v1), v2), v3);
        }
        public static void Main(string[] args)
        {
            Console.WriteLine(AddThree(0, 123, 456, 789));
        }
    }
}

Note that the inner method does inherit scope from the outer method.

I think this is a pretty cool feature. It makes it possible to structure methods better by introducing smaller helper methods without ecposing them to any other method.

I don't think it will be used much. The problem being solved is not a problem many C# developers are concerned about.

Pattern matching

C# 7 support for pattern matching as known in many FP (Functional Programming) languages.

This means that it is easy to test not only for values but also for types.

This is done via a new variant of if:

if(varname is typename newvarname)

and new variants of switch case:

switch(varname)
{
    ...
    case typename newvarname:
    ...
}

and:

switch(varname)
{
    ...
    case typename newvarname when condition:
    ...
}

Previous:


using System;

namespace E
{
    public class Program
    {
         public static void Test(object o)
         {
             if(o is int)
             {
                 int vi = (int)o;
                 Console.WriteLine(vi);
             }
             if(o is string)
             {
                 string vs = (string)o;
                 Console.WriteLine(vs);
             }
         }
         public static void Main(string[] args)
         {
             Test(123);
             Test("ABC");
         }
    }
}

Now this can be sligtly simplified using if:

using System;

namespace E
{
    public class Program
    {                     
         public static void Test(object o)
         {
             if(o is int vi)
             {
                 Console.WriteLine(vi);
             }
             if(o is string vs)
             {
                 Console.WriteLine(vs);
             }
         }
         public static void Main(string[] args)
         {
             Test(123);
             Test("ABC");
         }
    }
}

And simplified a lot by using switch:

using System;

namespace E
{
    public class Program
    {      
         public static void Test(object o)
         {
             switch(o)
             {
                case int vi: Console.WriteLine(vi);
                             break;
                case string vs: Console.WriteLine(vs);
                                break;
             }
         }
         public static void Main(string[] args)
         {
             Test(123);
             Test("ABC");
         }
    }
}

Note that since a given value now can match multiple cases, then the order of cases becomes significant.

Also note that the default case is always tested last even if it is not last in order.

I think this feature can be very useful at least for some types of programming.

I am unsure about how much it will be used. It is a rather advanced feature and even though it is useful then many C# developers may skip it due to its complexity.

Expresssion body

C# 7 got improved support for expression bodies. Again something more FP (Functional Programming) oriented.

First some traditional code:

using System;

namespace E
{
    public class Test
    {
        private int v;
        public Test(int v)
        {
            this.v = v;
        }
        public int V { get { return v; } }
        public void Demo() 
        {
            Console.WriteLine(v);
        }
    }
    public class Program
    {
         public static void Main(string[] args)
         {
             Test o = new Test(123);
             o.Demo();
         }
    }
}

C# 6 introduced a new feature that allowed an expression body for methods, so the code could be written as:

using System;

namespace E
{
    public class Test
    {
        private int v;
        public Test(int v)
        {
            this.v = v;
        }
        public int V { get { return v; } }
        public void Demo() => Console.WriteLine(v);
    }
    public class Program
    {
         public static void Main(string[] args)
         {
             Test o = new Test(123);
             o.Demo();
         }
    }
}

C# 7 extended this to properties and constructors as well, so the code can be written as:

using System;

namespace E
{
    public class Test
    {
        private int v;
        public Test(int v) => this.v = v;
        public int V { get => v; }
        public void Demo() => Console.WriteLine(v);
    }
    public class Program
    {
         public static void Main(string[] args)
         {
             Test o = new Test(123);
             o.Demo();
         }
    }
}

I don't think this feature is particular useful. It saves some line breaks and curly brackets, but I don't see the code as being more readable.

And I don't think it will be used much. Nobody used it for methods in the C# 6.

Missing

A few features was supposed to be in C# 7, but I can not get them to work.

This includes:

Somehow they did not make it.

Next:

See .NET 4.7.1/4.7.2/4.8 and C# 7.1/7.2/7.3/8.0 New Features.

Article history:

Version Date Description
1.0 February 13th 2017 Initial version
1.1 March 16th 2017 Update after final release
1.2 March 23rd 2017 Add release dates

Other articles:

See list of all articles here

Comments:

Please send comments to Arne Vajhøj