Inexplicable CS8978 'T' cannot be made nullable

See original GitHub issue

Version Used: Visual Studio 2022, .NET 6.0

Steps to Reproduce:

Create a new C# library in Visual Studio 2022. Add this class:

public sealed class Element<T>
{
    public Element(T key)
    {
        Key = key;
    }

    public T Key { get; }
    public Element<T>? Next { get; set; }

    public readonly static IEqualityComparer<Element<T>> Comparer = new ElementSnapshotComparer();

    public class ElementSnapshotComparer : IEqualityComparer<Element<T>>
    {
        public bool Equals(Element<T>? x, Element<T>? y)
        {
            return Equals(x?.Key, y is null ? null : y.Key) && Equals(x?.Next, y?.Next);
        }

        public int GetHashCode([DisallowNull] Element<T> obj)
        {
            return HashCode.Combine(obj.Key, obj.Next);
        }
    }
}

Expected Behavior:

The code compiles.

Actual Behavior:

The code doesn’t compile. Instead, it fails to compile with this error message:

Error CS8978 ‘T’ cannot be made nullable.

The offending expression is x?.Key, even though it was suggested by Visual Studio.

Notice the alternative null check made for y: y is null ? null : y.Key, which does compile. I left the two alternative versions side by side to be able to talk about the different compiler behaviour.

For the y is null ? null : y.Key expression, Visual Studio helpfully suggests IDE0031 Null check can be simplified, which, if followed, refactors the expression to y?.Key, which then also fails to compile.

I’ve tried to search for CS8978, but haven’t found anything that looks relevant. While I’m aware of #59805, it doesn’t look like the same issue to me.

It’s possible that this is correct behaviour, and that I’m just too ignorant to understand that this is so. If so, however, may I suggest a more helpful error message? (I have 20 years of C# experience, so if this confuses me, it may confuse other people, too.)

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
ploehcommented, Oct 2, 2022

Constraining T to ‘class’ will make the error go away. The compiler is worried about T being a struct.

Two reactions to that:

  1. One major use case is that I need T ~ int, so that is not a useful option.
  2. x and y, above, are not of the type T. They are of the type Element<T>, which is literally a class. If “The compiler is worried about T being a struct.”, I have to admit that I understand nothing. Why is that even relevant?
0reactions
CyrusNajmabadicommented, Oct 2, 2022

Thanks. Def an issue for IDE side to fix.

Read more comments on GitHub >

github_iconTop Results From Across the Web

CS0403, CS0037, CS8978 - Null assignment to nullable ...
Compiler error CS8978: 'T' cannot be made nullable. ... Constraining 'T' to struct or class makes the errors disappear.
Read more >
c# - Why is "default" different from "null" when assigning to ...
My real question is "Why doesn't it work!!?!?!" :) Note: A similar question was properly answered here: C#'s can't make `notnull` type nullable...
Read more >
Untitled
T cannot be made nullable WebOct 16, 2008 · The only problem is that this does not ... 'T' because it could Inexplicable...
Read more >
Resolve nullable warnings
Several compiler warnings indicate code that isn't null-safe. Learn how to address those warnings by making your code more resilient.
Read more >
Return null from a generic function? : r/csharp
As it says in the error, you can't return null, because T could be a non-nullable value type. If you want to only...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found