Tuesday, October 29, 2019

Visual C# Technical Guru - September 2019

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in Official Blog,

Regards,
Jaliya

Monday, October 28, 2019

C# 8.0: Using Declarations and Pattern-Based Using for Ref Structs

In this post, let's go through another feature that was introduced with C# 8.0 which is using declarations and pattern-based using for ref structs.

We are all familiar with using statements. So basically a using statement is something like this.
using (MyDisposableClass myDisposableClass = new MyDisposableClass())
{
    // some code
}
But to this, your MyDisposableClass needs to implement the interface IDisposable.
public class MyDisposableClass : IDisposable
{
    public void Dispose()
    {
        // some code to cleanup your resources
    }
}
And when the control is leaving enclosing scope, the Dispose method in MyDisposableClass will be called.

So what's wrong with this. There is actually nothing wrong, but using statements needs quite a bit of indenting to the code. If you are using multiple objects that need to be disposed of, the code is going to get a bit messy.
// some code 
using (var fileStream = new FileStream(...))
{
    // some code 
    using (var memoryStream = new MemoryStream())
    {
        // may be some other using statement ...
    }
}
Enter using declarations.
using MyDisposableClass myDisposableClass = new MyDisposableClass();
// some code
So now you can just declare the variable with using, and it will continue to work as it was. And when you have multiple usings,
{
    using var fileStream = new FileStream(...);
    using var memoryStream = new MemoryStream();
    ...
    // dispose of memoryStream
    // dispose of fileStream 
}
So here when the control is leaving the scope, the objects will be disposed in the reverse order in which they are declared.

The other feature is pattern-based using for ref structs. Ref strucs which was introduced with C# 7.2 is a struct declared with the ref modifier and it may not implement any interfaces, so can't implement IDisposable. But still, we can try and do something like this.
{
    using MyRefStruct myRefStruct = new MyRefStruct();
    // some code
}
But in order to that, we need to implement dispose pattern here, that is we have a Dispose method, which is public, parameterless and has a void return type.
public ref struct MyRefStruct
{
    public void Dispose()
    {
        // some code to cleanup your resources
    }
}
So in the using, as the control leaves the enclosing scope, the Dispose method will be called.

Hope this helps.

Happy Coding.

Regards,
Jaliya

Saturday, October 26, 2019

C# 8.0: Default Implementations of Interface Members

C# 8.0 has introduced some great features to the language and one of them is being able to have default implementations for Interface members. A couple of other features are also introduced to Interfaces to support and enhance this feature.

In this post, let's see have a look at what this really is. And to try this out, you’ll need to set up your machine to run .NET Core, including the C# 8.0 compiler. The C# 8.0 compiler is available starting with Visual Studio 2019 version 16.3 or the .NET Core 3.0 SDK.

Up to C# 8.0, this is what we know of Interfaces in .NET.
  • Interface members cannot have a definition / cannot have implementations
  • Interfaces cannot contain fields
  • For interface member declarations, only the new modifier is valid, you can't have any other modifiers like public, protected, private, etc.
  • All the interfaces members are by default, public and abstract
But with C# 8.0, whole a lot of things have changed. The main thing is Interface members can now have a default implementation.

Previously if you add a new method to an interface, all of your classes implementing that interface need to implement that method. Otherwise, it's going throw compile-time errors in the related classes. We all know that is a huge pain. How about being able to define a default implementation in the interface itself and let your classes override whenever they wish to. This is exactly what this feature is all about.

Consider the below code.
public interface IMyInterface
{
    void MyFirstMethod()
    {
        throw new NotImplementedException();
    }
}
 
public class MyFirstClass : IMyInterface
{
    public void MyFirstMethod()
    {
        Console.WriteLine("Hello World");
    }
}
 
public class MySecondClass : IMyInterface { }
So above is not possible prior to C# 8.0, but perfectly valid with C# 8.0. Note: that a class does not inherit members from its interfaces; that is not changed by this feature. So this is not possible.
new MySecondClass().MyFirstMethod();
So along with this, the following are also possible.
  • An interface can have static fields, but not instance fields
  • Interfaces can now have private members
  • Interfaces can now also have static members. This is used for parameterization of the default implementation.
  • Interfaces can also have protected members. They are not accessible by the derived class but via the derived interface.
  • Interfaces can also have virtual members, but the class can’t override the method. An interface can only override it.

Isn't this great!

Happy Coding.

Regards,
Jaliya

Monday, October 7, 2019

.NET Core: Tiered Compilation

A couple of days back during the .NET Conf, there were some major announcements along with the release of .NET Core 3.0. In this post, I am going to write about something which has been there for almost a year, wasn't available by default, but with .NET Core 3.0, it will be enabled by default. This feature is called Tiered Compilation.

Before moving into Tiered Compilation, let's have a quick recap of how .NET Compilation works. First, the code we have written using high-level languages (C#, F#, etc.) will be compiled into an exe or dll which contains CIL (Common Intermediate Language). And during the run-time, the methods are compiled into Native/Machine code. This is being carried out by JIT (Just-In-Time Compiler) and the process is known as jitting. Basically, whenever some method is being called, that method gets jitted and being stored. When this method is called next time, the method won't get jitted again, instead, it will be loaded from the memory. So all the methods in our code were compiled ONLY ONCE.

Let's just go by an example. Imagine you have this MethodA(), which will get called when you are starting your application. And it will get called throughout the life cycle of your application. JIT can do a very good optimization for your MethodA() based on a variety of algorithms. But that would make your application start slowly. On the other hand, JIT can use a simple algorithm and jit the method fast, so your application would start faster, but the generated code might not be properly optimized and the MethodA() will perform slow.

Enter Tiered Compilation. With Tiered Compilation, based on the usage of a method, it can get jitted more than once and can be hot-swapped at runtime. So basically JIT can pick an approach to start the application fast, and then based on the usage of a method and if the method appears hot, it will compile the same method again to generate more efficient code and use it for future calls.

This is how the Tiered Compilation works. First Tiered Compilation breaks the code into 2 buckets.
  1. Code that is eligible for tiering
    1. Tier0
      • This is usually the less optimized code that is generated using minimal optimizations. That is when the method is first invoked, the Tier0 version generated.
    2. Tier1
      • This is whatever code the runtime thinks will run faster than Tier0. If any method appears hot, the runtime would jit the method again with a more optimized version and will replace Tier0.
  2. Code that is NOT eligible for tiering
    • Will be jitted as before Tiered Compilation was introduced
Tiered Compilation was added as an opt-in feature in .NET Core 2.1. But with .NET Core 3.0,  it is enabled by default.

To enable Quick JIT (Tier0 jitted code), update the .csproj as follows.
<PropertyGroup>
  <TieredCompilationQuickJit>true</TieredCompilationQuickJit>
</PropertyGroup>
To disable Tiered compilation,  update the .csproj as follows.
<TieredCompilation>false</TieredCompilation>

More information:
   Tiered Compilation
   Tiered Compilation Guide

Happy Coding.

Regards,
Jaliya