Saturday, August 31, 2019

Visual C# Technical Guru - July 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

Wednesday, August 21, 2019

C# 8.0: notnull Generic Constraint

A couple of months back I wrote a post about C# 8.0: Nullable Reference Types which is a feature coming with C# 8.0. A few days back Microsoft has released .NET Core 3.0 Preview 8. And from .NET Core 3.0 Preview 7 onwards, C# 8.0 is now considered feature complete.

In this post, let's go through this nice feature added regarding Nullable Reference Types which is notnull generic constraint. This feature was released with .NET Core 3.0 Preview 7. Nullable Reference Types is an opt-in feature, meaning it's not enabled by default. In this post, I am not going to explain how you can enable it, you can refer to the old post linked above for that. 

Consider the following code. I have a generic interface, a class that implements it. Even though I have added the interface and the class in the same file, consider this an external library. Now from the Main, I am creating an object of MyClass of type nullable string and calling its method. Note: I have enabled Nullable Reference Types.
#nullable enable
 
namespace ConsoleApp1
{
    interface IMyInterface<TIn>
    {
        void MyMethod(TIn input);
    }
 
    public class MyClass<TIn> : IMyInterface<TIn>
    {
        public void MyMethod(TIn input)
        {
            // some code which uses input
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            stringmyString = null;
 
            var myClass = new MyClass<string?>();
            myClass.MyMethod(myString);
        }
    }
}
The above code will not show any warnings. Now imagine for some reason, I don't want to allow the generic type to be nullable. Enter notnull Generic Constraint.

I can update the code as follows.
interface IMyInterface<TIn>
    where TIn : notnull
{
    void MyMethod(TIn input);
}
 
public class MyClass<TIn> : IMyInterface<TIn>
    where TIn : notnull
{
    public void MyMethod(TIn input)
    {
        // some code which uses input
    }
}
We need to add the constraint to both the interface and the class. As soon as we do that, the following line will issue a warning.
// Warning CS8714  The type 'string?' cannot be used as type parameter 'TIn' in the generic type or method 'MyClass<TIn>'.
// Nullability of type argument 'string?' doesn't match 'notnull' constraint.

var myClass = new MyClass<string?>();
We can fix the warning by update the code as follows.
var myClass = new MyClass<string>();
And then we will need to fix the next warning of trying to pass a nullable string to MyMethod.

I really find this a really handy feature. One of the best examples would be, Microsoft has already constrained Dictionary<TKey, TValue>, where TKey is now to be notnull, which disallows using null as a key.

Hope this helps.

Happy Coding.

Regards,
Jaliya