{"id":28822,"date":"2020-02-05T00:00:00","date_gmt":"2020-02-04T23:00:00","guid":{"rendered":"https:\/\/blexin.com\/le-novita-di-c-8-prima-parte\/"},"modified":"2021-05-20T18:41:32","modified_gmt":"2021-05-20T16:41:32","slug":"new-features-of-c-8-part-one","status":"publish","type":"post","link":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/","title":{"rendered":"New features of C# 8: part one"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"27466\" data-permalink=\"https:\/\/blexin.com\/en\/image00-10-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image00-10\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-27466\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">C# is the&nbsp;reference language of the Microsoft .NET world and is updated periodically. In Visual Studio 2019, .Net Core 3.x and .Net standard 2.1, we find support for version 8, which is enriched with many new features that are not only compiler functions applicable to any version of the .NET Framework or .NET Core, but there&#8217;s an explicit dependency on .NET Core 3. In this article, I will show you the first part of the new features introduced in this version.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><em>using<\/em><\/strong><strong>&nbsp;Declarations<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<em>using<\/em>&nbsp;statement tells the compiler that it must&nbsp;<em>Dispose<\/em>&nbsp;the variable at the end of the inclusion scope.<br>This keyword is used when we deal&nbsp;with&nbsp;resources that implement the IDisposable interface. It\u2019s a best practice to make the call to&nbsp;<em>Dispose&nbsp;<\/em>on these objects to immediately release the resources and use of&nbsp;<em>using<\/em>&nbsp;ensures that this always happens correctly. With&nbsp;<em>C# 8<\/em>&nbsp;we can omit round brackets and braces, and declare a variable simply by placing&nbsp;<em>using<\/em>&nbsp;before it:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nstatic int WriteLinesToFile(IEnumerable&lt;string&gt; lines)\n{\n\u00a0\u00a0\u00a0\u00a0using var file = new System.IO.StreamWriter(&quot;WriteLines.txt&quot;);\n\u00a0\u00a0\u00a0\u00a0\/\/ Notice how we declare skippedLines after the using statement.\n\u00a0\u00a0\u00a0\u00a0int skippedLines = 0;\n\u00a0\u00a0\u00a0\u00a0foreach (string line in lines)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\/\/Some code here...\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\/\/ Notice how skippedLines is in scope here.\n\u00a0\u00a0\u00a0\u00a0return skippedLines;\n\u00a0\u00a0\u00a0\u00a0\/\/ File is disposed here\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In this example, the file&nbsp;<em>Dispose<\/em>&nbsp;is executed when the closing brace for the method is reached. Similarly the&nbsp;<em>skippedLines<\/em>&nbsp;variable is visible until the end of the method. If we wanted to close the scope before the end of the stack, as usual, C# allows us to outline the scope of different stack variables by enclosing everything between braces.<br>Let\u2019s see what our code with the syntax previous to the new version of C# would have been like, and where the&nbsp;<em>Dispose<\/em>&nbsp;would have been executed:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nstatic int WriteLinesToFile(IEnumerable&lt;string&gt; lines)\n{\n\u00a0\u00a0\u00a0\u00a0\/\/ We must declare the variable outside of the using block\n\u00a0\u00a0\u00a0\u00a0\/\/ so that it is in scope to be returned.\n\u00a0\u00a0\u00a0\u00a0int skippedLines = 0;\n\u00a0\u00a0\u00a0\u00a0using (var file = new System.IO.StreamWriter(&quot;WriteLines.txt&quot;))\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0foreach (string line in lines)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Some code here...\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0} \/\/ File is disposed here\n\u00a0\u00a0\u00a0\u00a0return skippedLines;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In this case, the file&nbsp;<em>Dispose&nbsp;<\/em>is executed when the closing brace associated with the&nbsp;<em>using<\/em>&nbsp;instruction is reached and we must declare the&nbsp;<em>skippedLines<\/em>&nbsp;variable to the outside of the&nbsp;<em>using<\/em>&nbsp;block otherwise it would not be in scope to be returned.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Local static functions<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Since version 7.0, C# supports&nbsp;<em>local functions<\/em>: these are private methods nested in another member and can only be called by its container member and not outside of it:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic int Method()\n{\n\u00a0\u00a0\u00a0\u00a0int num;\n\u00a0\u00a0\u00a0\u00a0LocalFunction();\n\u00a0\u00a0\u00a0\u00a0return num;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0void LocalFunction() =&gt; num = 4;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In C# 8,&nbsp;<em>static local functions&nbsp;<\/em>are an extension of the local functions, you can now add the&nbsp;<em>static<\/em>&nbsp;modifier to make sure that this local function does not refer to variables in the scope of inclusion.<br>In the previous code, the local function&nbsp;<em>LocalFunction<\/em>&nbsp;accesses the&nbsp;<em>num<\/em>&nbsp;variable, declared in the scope of inclusion&nbsp;(the method&nbsp;<em>Method<\/em>). We cannot therefore declare&nbsp;<em>LocalFunction<\/em>&nbsp;with the&nbsp;<em>static<\/em>&nbsp;modifier.<br>In the following code instead, the local function&nbsp;<em>RectangleArea<\/em>&nbsp;can be static because it does not access any variable in the scope of inclusion:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\ndouble RectangleAreaCalculation()\n{\n\u00a0\u00a0\u00a0\u00a0double x = 10;\n\u00a0\u00a0\u00a0\u00a0double y = 3;\n\u00a0\u00a0\u00a0\u00a0return RectangleArea(x, y);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0static double RectangleArea(double length, double width) =&gt;\n\u00a0\u00a0\u00a0\u00a0length + width;\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Asynchronous streams<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s immediately give a simple example of how we could manage a data stream coming from an&nbsp;<em>iterator<\/em>&nbsp;until now:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic async Task&lt;List&lt;int&gt;&gt; GenerateSequence()\n{\n\u00a0\u00a0\u00a0\u00a0List&lt;int&gt; list = new List&lt;int&gt;() ;\n\u00a0\u00a0\u00a0\u00a0for (int i = 0; i &lt; 20; i++)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await Task.Delay(100);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0list.Add(i);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0return list;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">It is clear that, with this approach, if we wanted to print the items of the list in the console, we should wait to have the complete list available and then iterate on each item:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic async void PrintSequence()\n{\n\u00a0\u00a0\u00a0\u00a0List&lt;int&gt; list = await GenerateSequence();\n\u00a0\u00a0\u00a0\u00a0foreach (int num in list)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(num);\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">A support to asynchronous flows been introduced with C# 8.&nbsp;This feature leads the async\/await pattern, which I mentioned in my previous&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.blexin.com\/en-US\/Article\/Blog\/Async-and-await-in-real-applications-60\" target=\"_blank\">article<\/a>, to manage iterators. In practice, async streams&nbsp;are async methods that return an IAsyncEnumerable&lt;T&gt;, and that have a return expressed with a yeld (yeld return) to return the next items in the asynchronous stream as soon as they are available:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic async System.Collections.Generic.IAsyncEnumerable&lt;int&gt; GenerateSequence()\n{\n\u00a0\u00a0\u00a0\u00a0for (int i = 0; i &gt; 20; i++)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await Task.Delay(100);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0yield return i;\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Ultimately, we can use&nbsp;<em>await&nbsp;<\/em>to wait for an asynchronous call and in turn make asynchronous the&nbsp;<em>GenerateSequence()<\/em>&nbsp;function. The important difference is that the function does not return a&nbsp;<em>Task&lt;IEnumerable&lt;int&gt;&gt;<\/em>, but an&nbsp;<em>IAsyncEnumerable&lt;int&gt;.<\/em><br>This interface contains asynchronous members to scroll the stream. Actually, it is not the&nbsp;<em>IEnumerable<\/em>&nbsp;object that must be returned in asynchronous, but the stream of the elements.<br>To use an asynchronous flow, you need to add the keyword&nbsp;<em>await<\/em>&nbsp;before<em>&nbsp;foreach<\/em>&nbsp;when enumerating the stream elements:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nawait foreach (var number in GenerateSequence())\n{\n\u00a0\u00a0\u00a0\u00a0Console.WriteLine(number);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In this case, as we have an element available, it will be &#8220;printed&#8221; to console, without waiting to have the whole list available.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s take a look at the definition of the interface&nbsp;<em>IAsyncEnumerator:<\/em><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IAsyncEnumerator&lt;out T&gt; : IAsyncDisposable\n{\n\u00a0\u00a0\u00a0\u00a0T Current { get; }\n\u00a0\n\u00a0\u00a0\u00a0\u00a0ValueTask&lt;bool&gt; MoveNextAsync();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">You can notice the presence of the interface IAsyncDisposable that allows us to browse and to carry out the dispose of all the resources, all completely in asynchronous way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Struct ref Disposable<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A struct declared with the<em>&nbsp;ref&nbsp;<\/em>modifier cannot implement any interface and therefore cannot implement the&nbsp;<em>IDisposable&nbsp;<\/em>interface.<br>From now on, we can enable a&nbsp;<em>ref struct<\/em>&nbsp;for deletion if we add a public&nbsp;<em>void<\/em>&nbsp;<em>Dispose<\/em>&nbsp;method within it. This method will be automatically consumed by the instruction&nbsp;<em>using<\/em>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nclass Program\n{\n\u00a0\u00a0\u00a0static void Main(string&#x5B;] args)\n\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0using (var message = new Message())\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;This message will self-destruct!&quot;);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0}\n}\n\u00a0\nref struct Message : IDisposable\n{\n\u00a0\u00a0\u00a0public void Dispose()\n\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We can also apply this feature to&nbsp;<em>readonly ref struct&nbsp;<\/em>statements.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Unmanaged constructed types<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In C# 7.3 and earlier, a&nbsp;<em>constructed type<\/em>&nbsp;(a type that includes at least one type argument) cannot be an&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/builtin-types\/unmanaged-types\" target=\"_blank\" rel=\"noreferrer noopener\"><em>unmanaged type<\/em><\/a>.<br>With C# 8, a&nbsp;<em>constructed type<\/em>&nbsp;is&nbsp;<em>unmanaged<\/em>&nbsp;if it contains only unmanaged fields of types.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, given the following generic type of Person&lt;T&gt;:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic struct Person&lt;T&gt;\n{\n\u00a0\u00a0\u00a0\u00a0public T Age;\n\u00a0\u00a0\u00a0\u00a0public T NumberOfSons;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<em>Person&lt;int&gt;<\/em>&nbsp;type is an unmanaged type in C# 8 (because it contains only properties of type&nbsp;<em>int<\/em>: int is an&nbsp;<em>unmanaged<\/em>&nbsp;type). As with any unmanaged type, you can create a pointer to a variable of this type or allocate a memory block in the stack for instances of this type:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nSpan&lt;Person&lt;int&gt;&gt; statisticalResearch = stackalloc&#x5B; ]\n{\n\u00a0\u00a0\u00a0\u00a0new Person&lt;int&gt; { Age = 30, NumberOfSons = 1 },\n\u00a0\u00a0\u00a0\u00a0new Person&lt;int&gt; { Age = 45, NumberOfSons = 3 },\n\u00a0\u00a0\u00a0\u00a0new Person&lt;int&gt; { Age = 36, NumberOfSons = 0 }\n};\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Members of reading only<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can apply the&nbsp;<em>readonly<\/em>&nbsp;modifier to any member of a&nbsp;<em>struct<\/em>, indicating in fact that it will not change its state. Compared to the&nbsp;application&nbsp;of the modifier&nbsp;to the entire structure, this option allows for more granular control.<br>Within a method marked as&nbsp;<em>readonly<\/em>&nbsp;it is not possible to change the content of a&nbsp;<em>field<\/em>&nbsp;because this would generate a compilation error.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic struct Employee\n{\n\u00a0\u00a0\u00a0\u00a0public string FullName { get; set; }\n\u00a0\u00a0\u00a0\u00a0public double DaysWorked { get; set; }\n\u00a0\u00a0\u00a0\u00a0public double DailyWages{ get; set; }\n\u00a0\u00a0\u00a0\u00a0public double Salary =&gt; DailyWages * DaysWorked;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0public readonly override string ToString() \n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Compiling error\n\u00a0\u00a0\u00a0\u00a0DaysWorked = 30;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Salary is not readonly and generates a warning\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return $&quot;Salary for employee {Surname} {Name} is: {Salary}$&quot;;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<em>ToString()<\/em>&nbsp;method does not change the state. This condition may be indicated by adding the&nbsp;<em>readonly<\/em>&nbsp;modifier to the&nbsp;<em>ToString()<\/em>&nbsp;statement.<br>The previous change generates a compiler warning, because&nbsp;<em>ToString<\/em>&nbsp;accesses the&nbsp;<em>Salary&nbsp;<\/em>property, which is not marked as&nbsp;<em>readonly<\/em>:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>warning CS8656: Call to non-readonly member 'Employee.Salary.get' from a 'readonly' member results in an implicit copy of 'this'<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The compiler generates a warning when creating a defensive copy. The&nbsp;<em>Salary&nbsp;<\/em>property does not change the status, so you can correct the warning by adding the&nbsp;<em>readonly<\/em>&nbsp;modifier to the statement:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic readonly double Salary =&gt; DailyWages * DaysWorked;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Attention: the&nbsp;<em>readonly<\/em>&nbsp;modifier is required, the compiler does not assume that the access functions&nbsp;<em>get<\/em>&nbsp;do not change the status; you need to declare&nbsp;<em>readonly<\/em>&nbsp;explicitly. The automatically implemented properties are an exception<br>The compiler will in fact consider all the&nbsp;automatically implemented&nbsp;<em>Getters<\/em>&nbsp;as<em>&nbsp;readonly<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Interfaces<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is a novelty that I found very interesting: we can now add members to the interfaces and provide an implementation for those members. This feature also supports C# interoperability with Android (Java) or Swift APIs, which already have similar implementations. This language functionality is one of those that needs a specific runtime to be supported and allows API authors to add methods to an interface&nbsp;without compromising the origin or compatibility with existing implementations of that interface. Existing implementations inherit the default implementation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose you have an interface like the following:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IPrintable\n{\n\u00a0\u00a0\u00a0\u00a0void Print();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">And a class that implements it:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class EBook : IPrintable\n{\n\u00a0\u00a0\u00a0\u00a0public void Print()\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(&quot;Print&quot;);\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">If we need to add a new feature, we will usually add a new member to the interface, such as the&nbsp;<em>Download<\/em>&nbsp;method:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IPrintable\n{\n\u00a0\u00a0\u00a0\u00a0void Print();\n\u00a0\u00a0\u00a0\u00a0void Download(string path);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<em>EBook&nbsp;<\/em>class would return a compilation error similar to:&nbsp;\u2018<em>EBook\u2019 does not implement interface member \u2018IPrintable.Download(string)<\/em>\u2019,&nbsp;as it no longer correctly implements the interface.<br>C# 8 introduces the&nbsp;<em>default interface<\/em>&nbsp;<em>methods<\/em>&nbsp;with which we can have a default implementation of a member directly in the interface:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IPrintable\n{\n\u00a0\u00a0\u00a0\u00a0int NumberOfPages { get; set; }\n\u00a0\u00a0\u00a0\u00a0double PricePerPage { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/Default Get\n\u00a0\u00a0\u00a0\u00a0double Price { get =&gt; NumberOfPages * PricePerPage; } \n\u00a0\u00a0\u00a0\u00a0\/\/Short default Get \n\u00a0\u00a0\u00a0\u00a0\/\/double Price =&gt; NumberOfPages * PricePerPage;\n\u00a0\u00a0\u00a0\u00a0void Print();\n\u00a0\u00a0\u00a0\u00a0void Download(string path);\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine($\u201dDownload in {path}\u201d);\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The class that implements the interface is obliged to implement, as usual, the method without body, and can optionally implement and overwrite the&nbsp;<em>default methods<\/em>&nbsp;provided by the interface.<br><em>Default methods<\/em>&nbsp;are only visible if we use an interface variable and are not visible through the class implementing it. On the contrary, only the members implemented on it are visible.<br>Interfaces can now include static members (including fields and methods) and<em>&nbsp;virtual&nbsp;<\/em>(but in this case a class implementing the interface cannot override a&nbsp;<em>virtual<\/em>&nbsp;method, only an interface can do that).<br>C# 8 also allows us to specify access modifiers for members of an interface, which in previous versions were implicitly public. Any modifier is now permitted for interface members.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic interface IPrintable\n{\n\u00a0\u00a0\u00a0\u00a0void Print();\n\u00a0\u00a0\u00a0\u00a0private static string copyright = &quot;\u00a9 2005-2011 Blexin s.r.l. All Rights Reserved&quot;;\n\u00a0\u00a0\u00a0\u00a0public virtual void PrintCopyright()\n\u00a0\u00a0\u00a0\u00a0{\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Console.WriteLine(copyright);\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s all for now, in the next article we will see what this new version of C# set aside for us.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">See you soon!<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Let\u2019s discover together what\u2019s new in C# 8<\/p>\n","protected":false},"author":196716244,"featured_media":27466,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637524],"tags":[688637384],"class_list":["post-28822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-en","tag-c-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>New features of C# 8: part one - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"New features of C# 8: part one - Blexin\" \/>\n<meta property=\"og:description\" content=\"Let\u2019s discover together what\u2019s new in C# 8\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2020-02-04T23:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-20T16:41:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Francesco Vastarella\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Francesco Vastarella\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/\"},\"author\":{\"name\":\"Francesco Vastarella\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/388dae0ca9df603c88b5e41e29cf2d4d\"},\"headline\":\"New features of C# 8: part one\",\"datePublished\":\"2020-02-04T23:00:00+00:00\",\"dateModified\":\"2021-05-20T16:41:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/\"},\"wordCount\":1509,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-10.png?fit=1024%2C608&ssl=1\",\"keywords\":[\"C#\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/\",\"name\":\"New features of C# 8: part one - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-10.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2020-02-04T23:00:00+00:00\",\"dateModified\":\"2021-05-20T16:41:32+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/388dae0ca9df603c88b5e41e29cf2d4d\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-10.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-10.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/new-features-of-c-8-part-one\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"New features of C# 8: part one\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/388dae0ca9df603c88b5e41e29cf2d4d\",\"name\":\"Francesco Vastarella\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g\",\"caption\":\"Francesco Vastarella\"},\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/author\\\/francesco-vastarellablexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"New features of C# 8: part one - Blexin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/","og_locale":"en_US","og_type":"article","og_title":"New features of C# 8: part one - Blexin","og_description":"Let\u2019s discover together what\u2019s new in C# 8","og_url":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/","og_site_name":"Blexin","article_published_time":"2020-02-04T23:00:00+00:00","article_modified_time":"2021-05-20T16:41:32+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Francesco Vastarella","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Francesco Vastarella","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/"},"author":{"name":"Francesco Vastarella","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/388dae0ca9df603c88b5e41e29cf2d4d"},"headline":"New features of C# 8: part one","datePublished":"2020-02-04T23:00:00+00:00","dateModified":"2021-05-20T16:41:32+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/"},"wordCount":1509,"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1","keywords":["C#"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/","url":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/","name":"New features of C# 8: part one - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1","datePublished":"2020-02-04T23:00:00+00:00","dateModified":"2021-05-20T16:41:32+00:00","author":{"@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/388dae0ca9df603c88b5e41e29cf2d4d"},"breadcrumb":{"@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/en\/blog-en\/new-features-of-c-8-part-one\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/en\/"},{"@type":"ListItem","position":2,"name":"New features of C# 8: part one"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/en\/#website","url":"https:\/\/blexin.com\/en\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/388dae0ca9df603c88b5e41e29cf2d4d","name":"Francesco Vastarella","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3b8deedae8f35372d5fba49f918006fb0a58a2943aff6ae52d3ff188e0c441bb?s=96&d=identicon&r=g","caption":"Francesco Vastarella"},"url":"https:\/\/blexin.com\/en\/author\/francesco-vastarellablexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-10.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-7uS","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/users\/196716244"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/comments?post=28822"}],"version-history":[{"count":2,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28822\/revisions"}],"predecessor-version":[{"id":31947,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28822\/revisions\/31947"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media\/27466"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media?parent=28822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/categories?post=28822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/tags?post=28822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}