Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Casting object? to a generic type that may or may not be nullable

I’m trying to convert a project to use nullable reference types, but I’m running into an issue. In my project, I have a place where I get an object? that needs to be cast to a generic type T before adding it to a collection. The type T could be anything; a nullable reference type, a non-nullable reference type, or a value type. This isn’t known at compile time.

So, let’s say I have the following code (toy example):

static T Convert<T>(object? value)
{
    return (T)value;
}

This causes the compiler to complain that value may be null, and that the return of the function may be null. That’s fair enough, since if T is non-nullable and value is null, this wouldn’t be allowed. I thought maybe this would work:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

static T Convert<T>(object? value)
{
    if (value == null)
        return default;
    else
        return (T)value;
}

But this has the same problem: if T is a non-nullable reference type, default is still null, which still violates the constraint.

Making the function return T? is not a solution, because in the case of value types, I don’t want to use Nullable<T>.

I thought about throwing an exception if value is null, but I want to allow null if T is nullable. So I’d only want to throw that if T is non-nullable, and that kind of generic specialization doesn’t seem possible in C#.

The context here is that I’m using a TypeConverter, and unfortunately the result of conversion is allowed to return null.

Is there a good way to handle this situation?

>Solution :

If you use C# 9.0 or higher, you can use return type of T? without need to resort to Nullable<T>. For generics in non-nullable context there is special set of rules, detailed here.

If the type argument for T is a value type, T? references the same value type, T. For example, if T is an int, the T? is also an int.

You can check GetType() of T with simple console application. If T is int, return type will be System.Int32, not Nullable<System.Int32>.

#nullable enable
using System;

public class Program
{
    public static void Main()
    {
        var result = Convert<int>(null);
        Console.WriteLine(result); // Prints: 0
        Console.WriteLine(result.GetType().FullName); // Prints: System.Int32
    }

    static T? Convert<T>(object? value)
    {
        if (value is null)
            return default(T);
        return (T)value;
    }
}

C# Playground example here.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading