0

I want to create a Blazor(wasm) InputNumber<T> component where T : INumber<T>.

Inside this component I have a simple function to set the Value:

this compiles good

void SetValue(T? value)
{
    if (value is null)
    {
       ....
    }
    ....
}

but when I try to call SetValue(null) the compiler says:

CS1503: "cannot convert from <null> to T?"

I was expecting that if the method parameter is T? then I should be able to pass null to it.
e.g.

void SetDecimal(decimal? value)
{
    if (value is null)
    {
      ...
    }
}

This of course works: SetDecimal(null);

What am I missing?

GSerg
  • 76,472
  • 17
  • 159
  • 346
Ran Karat
  • 21
  • 4
  • Does this answer your question? [Why T? is not a nullable type?](https://stackoverflow.com/questions/69353518/why-t-is-not-a-nullable-type) – GSerg Feb 02 '23 at 11:01

1 Answers1

2

The problem here arises from the difference between how nullable value and nullable reference types work - former are actually represented as separate type Nullable<T> while latter are not and represented by the runtime as metadata. Which results in a bit non-intuitive generic handling of T? depended on the constraints (see more in the docs or here).

One of the possible workarounds is to limit T to struct (if it is usable for you):

void SetValue<T>(T? value) where T: struct
{
    if (value is null)
    {
    }
}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    After reading your suggestion i added it to the Component generic constraints, but i took a different approach on settings the Value by checking if the type is Nullable: bool isNullable = Nullable.GetUnderlyingType(typeof(T)) != null; so if it is, i just set it to default (which will be null in case its nullable) and if it isn't i need to make some calculation to Set the right value. Thanks! – Ran Karat Feb 02 '23 at 11:47
  • @RanKarat was glad to help! If answer works for you - feel free to mark it as accepted one. Or post yours and mark it. – Guru Stron Feb 02 '23 at 12:40
  • well it helped me to take other aproch but what i really wanted to reach was: using System.Numerics; namespace ConsoleApp3; public class Number where T : struct, INumber{ } MyNumber myNumber = new(); above line make a compile time error: "The type int? must be a non-nullable value type in order to use it as parameter T in the generic type or method MyNumber" i want to be able to use nullable types with INumber. – Ran Karat Feb 04 '23 at 09:13
  • @RanKarat yep, that is not possible at the moment as far as I understand. Until C# team will implement lifting for `INumber`. – Guru Stron Feb 07 '23 at 16:40