5

Suppose we have a generic method which accepts INumber<T> and returns int:

// process val and return as int
static int DoSomething<T>(T val) where T : INumber<T> => ... 

How can the T be casted to int.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • 1
    What if `T` is a double? Would that be an error or is there some conversion you want to define (round, floor, etc.)? – D Stanley Feb 28 '23 at 15:21
  • @DStanley the question description refers to the desired operation as "cast", though exactly the same behavior is not achievable it seems. – Guru Stron Feb 28 '23 at 16:03
  • Correct, because you can't actually "cast" a `double` to an `int`. If you use the "cast" syntax at compile time, the compiler actually does a "conversion". If you try to do a cast at runtime it will fail. You need to be explicit on how you want to convert any numeric value to an integer generically. – D Stanley Feb 28 '23 at 16:41

1 Answers1

9

INumberBase<TSelf> defines several CreateX operations which can be used to convert generic value to the target one (and vice versa):

static int DoSomething<T>(T val) where T : INumber<T> => int.CreateChecked(val);

Note that based on method and type pair used the result can differ from casting:

var d = double.MaxValue - 1;
unchecked
{
    Console.WriteLine((int)d); // -2147483648
    // Console.WriteLine(int.CreateChecked(d)); // throws
}

Console.WriteLine(int.CreateSaturating(d)); // 2147483647
Console.WriteLine(int.CreateTruncating(d)); // 2147483647

So use with caution.

Demo.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132