{"id":2122,"date":"2015-11-30T00:00:00","date_gmt":"2015-11-30T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/whats-new-in-c-6\/"},"modified":"2021-05-17T18:35:55","modified_gmt":"2021-05-17T18:35:55","slug":"whats-new-in-c-6","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/whats-new-in-c-6\/","title":{"rendered":"What&#8217;s New in C# 6"},"content":{"rendered":"<div class=\"article-content\">\n<p class=\"start\">Version 6 of the .NET C# programming language was introduced when Visual Studio 2015 was recently released. What were the most significant improvements in the language?<\/p>\n<p>The main focus of the release was the new compiler platform (known as &#8216;Roslyn&#8217;): There weren&#8217;t many obvious improvements or additions to the language as such, but the changes that I&#8217;ll mention in this article will definitely be appreciated by anyone who uses the C# programming language to develop applications.<\/p>\n<h2>Improvements in Auto-Properties<\/h2>\n<p>C# has &#8216;auto-implemented properties&#8217; (or, more concisely, &#8216;auto-properties&#8217;) that make property-declaration for simple properties more concise. Behind the scenes, a private, anonymous backing field is created that can be read or updated only via the property&#8217;s <code>get<\/code> and <code>set<\/code> accessors. They are declared with the <code>get<\/code> and <code>set<\/code> keyword followed by a semicolon.<\/p>\n<h3>Initializers for Auto-Properties<\/h3>\n<p>It is now possible to declare the auto-properties just as you would a field:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public class Person\r\n{\r\n    public string First { get; set; } = \"Jane\";\r\n    public string Last { get; set; } = \"Doe\";\r\n}\r\n<\/pre>\n<p>With this syntax, the initializer directly initializes the field that supports the property without actually using the <code>set<\/code> accessor of the property.<\/p>\n<p>The property initializers are executed in the order they are declared, just as and along with field initializers. After all, they are, in fact, field initializers.<\/p>\n<p>As with the field initializers, property initializers cannot refer to this because like field initializers, they run before the object is properly initialized.<\/p>\n<p>The implementation of this new functionality is actually syntactic sugar, in that it generates code that is compatible with previous versions of the .NET platform. In fact, the code I&#8217;ve used to illustrate the new syntax is translated by the compiler to the following C# code 1:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public class Person\r\n{\r\n    [CompilerGenerated]\r\n    [DebuggerBrowsable(DebuggerBrowsableState.Never)]\r\n    public string &lt;First&gt;k__BackingField = \"Jane\";\r\n    [CompilerGenerated]\r\n    [DebuggerBrowsable(DebuggerBrowsableState.Never)]\r\n    public string &lt;Last&gt;k__BackingField = \"Doe\";\r\n\r\n    public string First\r\n    {\r\n        [CompilerGenerated]\r\n        get { return &lt;First&gt;k__BackingField }\r\n        [CompilerGenerated]\r\n        set { &lt;First&gt;k__BackingField = value; }\r\n    }\r\n    public string Last\r\n    {\r\n        [CompilerGenerated]\r\n        get { return &lt;Last&gt;k__BackingField }\r\n        [CompilerGenerated]\r\n        set { &lt;Last&gt;k__BackingField = value; }\r\n    }\r\n}\r\n<\/pre>\n<p>Note that the <code>&lt;First&gt;k__BackingField<\/code> and <code>&lt;Last&gt;k__BackingField<\/code> have names that are not valid C# names. This is done to ensure that there is no chance of collision between a name that is given by the programmer and a name given by the compiler.<\/p>\n<h3>Read-Only Auto-Properties<\/h3>\n<p>If you only declare a <code>get<\/code> accessor, then the property is immutable everywhere except in its initializer and the constructor, so that it becomes read-only:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public class Person\r\n{\r\n    public string First { get; } = \"Jane\";\r\n    public string Last { get; } = \"Doe\";\r\n}\r\n<\/pre>\n<p>In this case, the field is declared generated as <code>readonly<\/code> (although this has importance only for the purpose of reflection).<\/p>\n<p>As in the previous case, the generated code will be:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public class Person\r\n{\r\n    [CompilerGenerated]\r\n    [DebuggerBrowsable(DebuggerBrowsableState.Never)]\r\n    private readonly string &lt;First&gt;k__BackingField = \"Jane\";\r\n    [CompilerGenerated]\r\n    [DebuggerBrowsable(DebuggerBrowsableState.Never)]\r\n    private readonly string &lt;Last&gt;k__BackingField = \"Doe\";\r\n\r\n    public string First\r\n    {\r\n        [CompilerGenerated]\r\n        get { return &lt;First&gt;k__BackingField; }\r\n    }\r\n    public string Last\r\n    {\r\n        [CompilerGenerated]\r\n        get { return &lt;Last&gt;k__BackingField; }\r\n    }\r\n}\r\n<\/pre>\n<p>As with the read-only fields, you can also initialize a read-only auto-property in the constructor.<\/p>\n<pre class=\"lang:c# theme:vs2012\">public class Person\r\n{\r\n    \/\/ ...\r\n\r\n    public Person(string first, string last)\r\n    {\r\n        First = first;\r\n        Last = last;\r\n    }\r\n}\r\n<\/pre>\n<p>And, once again, the equivalent compiler generates code C# 1:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public class Person\r\n{\r\n    \/\/ ...\r\n\r\n    public Person(string first, string last)\r\n    {\r\n        &lt;First&gt;k__BackingField = first;\r\n        &lt;Last&gt;k__BackingField = last;\r\n    }\r\n}\r\n<\/pre>\n<h2>Expression Bodied Function Members<\/h2>\n<p>We can now use the same convenient fat arrow expression syntax (<code>=&gt;<\/code>) to define lambda expressions to define function bodies.<\/p>\n<h3>Expression Bodied Method-Like Members<\/h3>\n<p>We use the lambda fat arrow (<code>=&gt;<\/code>) to define the body of methods as well as user-defined operators, type conversions and indexers. The expression to the right of the lambda arrow represents the body of the method.<\/p>\n<pre class=\"lang:c# theme:vs2012\">public Point Move(int dx, int dy) =&gt; new Point(x + dx, y + dy);\r\npublic static Complex operator +(Complex a, Complex b) =&gt; a.Add(b);\r\npublic static implicit operator string (Person p) =&gt; p.First + \" \" + p.Last;\r\n<\/pre>\n<p>The effect is exactly the same as if the methods have only a return statement. The above examples are translated by the compiler to:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public Point Move(int dx, int dy)\r\n{\r\n    return new Point(x + dx, y + dy);\r\n}\r\npublic static Complex operator +(Complex a, Complex b)\r\n{\r\n    return a.Add(b);\r\n}\r\npublic static implicit operator string (Person p)\r\n{\r\n    return p.First + \" \" + p.Last;\r\n}\r\n<\/pre>\n<p>For methods whose return type is <code>void<\/code> (or Task for asynchronous methods), the lambda arrow (<code>=&gt;<\/code>) syntax still applies but the subsequent expression must be a statement (this is similar to what already happens with lambdas):<\/p>\n<pre class=\"lang:c# theme:vs2012\">public void Print() =&gt; Console.WriteLine(First + \" \" + Last);\r\n<\/pre>\n<p>&#8230;will be translated into&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">public void Print()\r\n{\r\n    Console.WriteLine(First + \" \" + Last);\r\n}\r\n<\/pre>\n<h3>Expression Bodied Property-Like Function Members<\/h3>\n<p>Expression bodies can also be used to define the body of properties and an indexers:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public string Name =&gt; First + \" \" + Last;\r\npublic Person this[long id] =&gt; store.LookupPerson(id);\r\n<\/pre>\n<p>Note the absence of the <code>get<\/code> keyword, which instead is implied by the syntax of the expression.<\/p>\n<p>The previous examples are translated by the compiler to:<\/p>\n<pre class=\"lang:c# theme:vs2012\">public string Name\r\n{\r\n    get\r\n    {\r\n        return First + \" \" + Last;\r\n    }\r\n}\r\npublic Person this[long id]\r\n{\r\n    get\r\n    {\r\n        return store.LookupPerson(id);\r\n    }\r\n}\r\n<\/pre>\n<h2>The &#8216;using static&#8217; Directive<\/h2>\n<p>We can now import the static or enumerated members of a class into our namespace. We can then use the static members of a class directly without qualifying them with their namespace or type name!<\/p>\n<pre class=\"lang:c# theme:vs2012\">using static System.Console;\r\nusing static System.Math;\r\nusing static System.DayOfWeek;\r\nclass Program\r\n{\r\n    static void Main()\r\n    {\r\n        WriteLine(Sqrt(3 * 3 + 4 * 4));\r\n        WriteLine(Friday - Monday);\r\n    }\r\n}\r\n<\/pre>\n<p>The previous code is translated by the compiler to:<\/p>\n<pre class=\"lang:c# theme:vs2012\">class Program\r\n{\r\n    static void Main()\r\n    {\r\n        System.Console.WriteLine(System.Math.Sqrt(3 * 3 + 4 * 4));\r\n        System.Console.WriteLine(System.DayOfWeek.Friday - System.DayOfWeek.Monday);\r\n    }\r\n}\r\n<\/pre>\n<p>This feature is great when you have a set of related functions with a particular domain that is often used, such as <code>System.Math<\/code>. We can reference the methods of the <code>Math<\/code> class as though they were members of the class invoking them. It also allows you to specify the names of the members of an enumerated class as members of <code>System.DayOfWeek<\/code> in the example above.<\/p>\n<h3>Extension Methods<\/h3>\n<p>Extension methods are invoked like regular static methods, (See: <a href=\"https:\/\/msdn.microsoft.com\/en-gb\/magazine\/dn879355.aspx\">https:\/\/msdn.microsoft.com\/en-gb\/magazine\/dn879355.aspx<\/a>) but they are called as if they were instance methods on the extended type. Instead of bringing these methods to the current scope, the static import functionality makes these methods available as extension methods without the need to import all extension methods in a namespace like before:<\/p>\n<pre class=\"lang:c# theme:vs2012\">using static System.Linq.Enumerable; \/\/ The type, not the namespace\r\nclass Program\r\n{\r\n    static void Main()\r\n    {\r\n        var range = Range(5, 17);                \/\/ Ok: not extension\r\n        var odd = Where(range, i =&gt; i % 2 == 1); \/\/ Error, not in scope\r\n        var even = range.Where(i =&gt; i % 2 == 0); \/\/ Ok\r\n    }\r\n}\r\n<\/pre>\n<p>This means that it will now be a breaking change to change a normal static method into an extension method, which was not the case before. Extension methods are usually only invoked as static methods when there&#8217;s an ambiguity. And, in those cases, it seems legit to require full qualification anyway.<\/p>\n<h2>Null-Conditional Operator<\/h2>\n<p>It is often necessary to scatter null checks around code. Operators with null checks allow access to members and elements only when the receiver is not null, otherwise returning a null result:<\/p>\n<pre class=\"lang:c# theme:vs2012\">int? length = people?.Length; \/\/ null if people is null\r\nPerson first = people?[0];    \/\/ null if people is null \r\n<\/pre>\n<p>The above code is translated into:<\/p>\n<pre class=\"lang:c# theme:vs2012\">int? nullable = (people != null) ? new int?(people.Length) : null;\r\nPerson person = (people != null) ? people[0] : null;\r\n<\/pre>\n<p>The null-conditional operators can be very convenient when used with the coalesce operator <code>(??)<\/code>:<\/p>\n<pre class=\"lang:c# theme:vs2012\">int length = people?.Length ?? 0; \/\/ 0 se people \u00e9 null\r\n<\/pre>\n<p>The null-conditional operators have a short-circuit behaviour. In the chain of access to members, elements or invocations immediately adjacent will only run if the original recipient is not null:<\/p>\n<pre class=\"lang:c# theme:vs2012\">int? first = people?[0].Orders.Count();\r\n<\/pre>\n<p>This example is, in essence, equivalent to:<\/p>\n<pre class=\"lang:c# theme:vs2012\">int? first = (people != null) ? people[0].Orders.Count() : (int?)null;\r\n<\/pre>\n<p>&#8230;except that <code>people<\/code> is evaluated only once. None of the access to members or elements and invocations that follow the ? operator will run if the value of <code>people<\/code> is null.<\/p>\n<p>Nothing prevents null-conditional operators from being chained, if null verification is required more than once in the chain:<\/p>\n<pre class=\"lang:c# theme:vs2012\">int? first = people?[0]?.Orders.Count();\r\n<\/pre>\n<p>In an invocation, a list of arguments in parentheses cannot be immediately preceded by the &#8216;<code>?<\/code>&#8216; operator &#8211; It would lead to too many ambiguities. Therefore, the invoking of a delegate that one might expect if it is not null is not allowed. However, the delegate can always be invoked via its <code>Invoke<\/code> method:<\/p>\n<pre class=\"lang:c# theme:vs2012\">if (predicate?.Invoke(e) ?? false) { ... }\r\n<\/pre>\n<p>A common use of this feature is the event trigger:<\/p>\n<pre class=\"lang:c# theme:vs2012\">PropertyChanged?.Invoke(this, args);\r\n<\/pre>\n<p>&#8230;which is translated to&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">var handler = PropertyChanged;\r\nif (handler != null)\r\n{\r\n    handler.Invoke(this, args);\r\n}\r\n<\/pre>\n<p>This is a thread-safe way to see if the event has subscribers, because it only evaluates the left side of the invocation once, and keeps its value in a temporary variable. Without this feature, you used to have to write to this pattern yourself.<\/p>\n<h2>String Interpolation<\/h2>\n<p>The <code>String.Format<\/code> method, and other similar methods, is very versatile and useful, but its use is a bit awkward and error-prone due to numerical markers (<code>{0}<\/code>) that must match the position of the arguments supplied separately:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var s = string.Format(\"{0} is {1} year{{s}} old.\", p.Name, p.Age);\r\n<\/pre>\n<p>The interpolation syntax allows strings to directly replace the literal string indexes by &#8220;holes&#8221; with the expressions that correspond to the values:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var s = $\"{p.Name} is {p.Age} year{{s}} old.\";\r\n<\/pre>\n<p>As with the <code>String.format<\/code> method, it is possible to specify shapes and alignments:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var s = $\"{p.Name,20} is {p.Age:D3} year{{s}} old.\";\r\n<\/pre>\n<p>The content of the holes can be any expression, including strings:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var s = $\"{p.Name} is {p.Age} year{(p.Age == 1 ? \"\" : \"s\")} old.\";\r\n<\/pre>\n<p>Note that the conditional expression is in brackets, so that: &#8220;s&#8221; is not confused with the format specifier.<\/p>\n<h3>Formattable Strings<\/h3>\n<p>When not otherwise specified, a formatting provider uses the current culture of the current thread when invoking the <code>String.Format<\/code> method, but this is not always what is wanted. That is why, as happens with lambda expressions, the compiler translates the interpolated string differently depending on the type of receptor expression.<\/p>\n<p>If the receiver of expression is the <code>IFormattable<\/code> type&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">IFormattable christmas = $\"{new DateTime(2015, 12, 25):f}\";\r\n<\/pre>\n<p>&#8230;the compiler generates the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">IFormattable christmas = FormattableStringFactory.Create(\"{0:f}\", new DateTime(2015, 12, 25));\r\n<\/pre>\n<p>This can be used as follows:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var christamasText = christmas.ToString(null, new CultureInfo(\"pt-PT\"));\r\n<\/pre>\n<h4><code>FormattableString<\/code><\/h4>\n<p>The concrete type returned by <code>FormattableStringFactory.Create<\/code> is derived from:<\/p>\n<pre class=\"lang:c# theme:vs2012\">namespace System\r\n{\r\n    public abstract class FormattableString : IFormattable\r\n    {\r\n        protected FormattableString();\r\n        public abstract int ArgumentCount { get; }\r\n        public abstract string Format { get; }\r\n        public static string Invariant(FormattableString formattable);\r\n        public abstract object GetArgument(int index);\r\n        public abstract object[] GetArguments();\r\n        public override string ToString();\r\n        public abstract string ToString(IFormatProvider formatProvider);\r\n    }\r\n}\r\n<\/pre>\n<p>This provides access not only the format but also to the format string arguments.<\/p>\n<h4>Backward Compatibility<\/h4>\n<p>The features introduced by the C# 6 are compatible with the previous .NET platforms. However, this particular feature requires <code>System.Runtime.CompilerServices.FormattableStringFactory<\/code> and <code>System.FormattableString<\/code> types that have been introduced only in version 4.6 of the platform. The good news is that the compiler is not tied to the location of these types in a particular assembly and, if we are to use this functionality in an earlier version of the platform, we just need to add the implementation of these types.<\/p>\n<h2>&#8216;nameof&#8217; Expressions<\/h2>\n<p>Occasionally it is necessary to provide a string with the name of some program elements.<\/p>\n<ul>\n<li>This can happen when throwing a <code>System.ArgumentNullException<\/code>;<\/li>\n<li>Firing a <code>PropertyChanged<\/code> event;<\/li>\n<li>And many other occasions.<\/li>\n<\/ul>\n<p>We can use string literals for this, but they are error prone and are not changed when a name is changed by a code refactoring.<\/p>\n<p>The <code>nameof<\/code> expressions are a sort of literal of type <code>string<\/code> in which the compiler validates the existence of something with that name. As it becomes a reference to the artefact, Visual Studio knows what it refers to and code navigation and refactoring work.<\/p>\n<p>In essence, code such as the following:<\/p>\n<pre class=\"lang:c# theme:vs2012\">if (x == null) throw new ArgumentNullException(nameof(x));\r\nvar s = nameof(person.Address.ZipCode);\r\n<\/pre>\n<p>is converted to:<\/p>\n<pre class=\"lang:c# theme:vs2012\">if (x == null) throw new ArgumentNullException(\"x\");\r\nvar s = \"ZipCode\";\r\n<\/pre>\n<h3>Source Code vs. Metadata<\/h3>\n<p>The names used by the compiler are the source names and not the metadata names of the artifacts, and so the following code&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">using S = System.String;\r\nclass C\r\n{\r\n    void M&lt;T&gt;(S s)\r\n    {\r\n        var s1 = nameof(T);\r\n        var s2 = nameof(S);\r\n    }\r\n}\r\n<\/pre>\n<p>&#8230;is converted to&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">using S = System.String;\r\nclass C\r\n{\r\n    void M&lt;T&gt;(S s)\r\n    {\r\n        var s1 = \"T\";\r\n        var s2 = \"S\";\r\n    }\r\n}\r\n<\/pre>\n<h3>Primitive Types<\/h3>\n<p>It is not allowed to use primitive types (<code>int<\/code>, <code>long<\/code>, <code>char<\/code>, <code>bool<\/code>, <code>string<\/code>, etc.) in <code>nameof<\/code> expressions because they are not expressions and the argument of <code>nameof<\/code> is an expression.<\/p>\n<h2>Add Extension Methods in Collection Initializers<\/h2>\n<p>When collection initializers were introduced in C#, the <code>Add<\/code> method calls could not be an extension method invocation. Visual Basic allowed its use but it seemed to have been forgotten for C#.<\/p>\n<p>In this version the fault has been corrected and it is now possible to use <code>Add<\/code> extension methods in collection initializers.<\/p>\n<p>It is a small but useful feature and, in terms of the implementation of the compiler, this was just the removal of the check of the condition that prevented it.<\/p>\n<h2>Index Initializers<\/h2>\n<p>Object and collection initializers are useful to initialize declaratively the fields and properties of objects or, in the case of collections, an initial set of elements.<\/p>\n<p>Initializing dictionaries, on the other hand, were not so elegant, requiring the existence of an <code>Add<\/code> method that received as an argument the key and the value corresponding to that key. If a dictionary implementation in particular did not have an <code>Add<\/code> method with the aforementioned characteristics, it would not be possible to use an initializer.<\/p>\n<p>From now on, it becomes possible to use initializers that use indexes:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var numbers = new Dictionary&lt;int, string&gt;\r\n{\r\n    [7] = \"sete\",\r\n    [9] = \"nove\",\r\n    [13] = \"treze\"\r\n};\r\n<\/pre>\n<p>which will be translated into:<\/p>\n<pre class=\"lang:c# theme:vs2012\">var dictionary = new Dictionary&lt;int, string&gt;();\r\ndictionary[7] = \"sete\";\r\ndictionary[9] = \"nove\";\r\ndictionary[13] = \"treze\";\r\nvar numbers = dictionary;\r\n<\/pre>\n<h2>Exception Filters<\/h2>\n<p>Exception filters a CLR feature already provided by Visual Basic and F# and will now also be available in C#:<\/p>\n<pre class=\"lang:c# theme:vs2012\">try\r\n{\r\n    ...\r\n}\r\ncatch (Exception ex) when (SomeFilter(ex))\r\n{\r\n    ...\r\n}\r\n<\/pre>\n<p>If the evaluation of the expression in parentheses after the <code>when<\/code> keyword evaluates to <code>true<\/code>, the exception is caught. Otherwise, the <code>catch<\/code> block is ignored.<\/p>\n<p>This allows them to be laid over a <code>catch<\/code> block for the same type of exception:<\/p>\n<pre class=\"lang:c# theme:vs2012\">try\r\n{\r\n    \/\/...\r\n}\r\ncatch (SqlException ex) when (ex.Number == 2)\r\n{\r\n    \/\/ ...\r\n}\r\ncatch (SqlException ex)\r\n{\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>In the example above, the first catch block is only executed if an exception of type <code>SqlException<\/code> in the value of the <code>Number<\/code> property is 2. Otherwise you run the next block.<\/p>\n<p>It is considered acceptable and commonplace &#8220;abuse&#8221; of exceptions filters with side effects such as logging.<\/p>\n<p class=\"note\">WARNING: Exception filters are executed in the context of the <code>throw<\/code> and not in the context of the <code>catch<\/code> because the stack hasn&#8217;t been unwound yet.<\/p>\n<h2>&#8216;await&#8217; in &#8216;catch&#8217; and &#8216;finally&#8217; blocks<\/h2>\n<p>C# 5 was not allowed to use the await keyword in catch and finally blocks because, at the time of implementation of the async-functionality await, the team thought that this would not be possible to implement. But later, they found out that, after all, it was not impossible, although it can lead to some <a href=\"https:\/\/clivetong.wordpress.com\/2015\/07\/22\/c-await-inside-catch-and-finally-leads-to-some-interesting-semantics\/\">interesting semantics<\/a>.<\/p>\n<p>It becomes possible to write code like this:<\/p>\n<pre class=\"lang:c# theme:vs2012\">Resource res = null;\r\ntry\r\n{\r\n    res = await Resource.OpenAsync();      \r\n\r\n}\r\ncatch (ResourceException e)\r\n{\r\n    await Resource.LogAsync(res, e);        \r\n}\r\nfinally\r\n{\r\n    if (res != null) await res.CloseAsync();         \r\n}\r\n<\/pre>\n<h2>Improvements in Overload Resolution Methods<\/h2>\n<p>They were introduced some improvements in overload method resolution (See: <a href=\"http:\/\/bc-programming.com\/blogs\/2015\/06\/c-6-features-improved-overload-resolution\/\">http:\/\/bc-programming.com\/blogs\/2015\/06\/c-6-features-improved-overload-resolution\/<\/a>) in order to make it more intuitive to determine how the compiler decides which method overloading to use.<\/p>\n<p>Where it is more noticeable is the choice of method overloading when receiving nullable value types, or when moving a group of methods (rather than a lambda) methods for overload receiving delegates.<\/p>\n<p>Resources:<\/p>\n<ol>\n<li><a href=\"https:\/\/github.com\/dotnet\/roslyn\/wiki\/New-Language-Features-in-C%23-6\">New Language Features in C# 6<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/dotnet\/roslyn\/issues\/2136\">C# 7 Work List of Features<\/a><\/li>\n<li><a href=\"https:\/\/msdn.microsoft.com\/library\/dn961160\">Interpolated Strings (C# and Visual Basic Reference)<\/a><\/li>\n<\/ol>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The C# language itself has changed little in version 6, the main importance of the release being the introduction of the Roslyn .NET Compiler Platform. However the New features and improvements that have been made to C# are welcome because they are aimed at aiding productivity. Paulo Morgado explains what they are, and how to use them.&hellip;<\/p>\n","protected":false},"author":151913,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4229,4371,4179],"coauthors":[59529],"class_list":["post-2122","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-net-framework","tag-c","tag-source-control"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/151913"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=2122"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2122\/revisions"}],"predecessor-version":[{"id":78947,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/2122\/revisions\/78947"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=2122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=2122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=2122"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=2122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}