I keep having use cases where it would be nice to have a parent Number
type that the numeric primitives inherit from, but to the best of my research, none exists. The next best solution I've found is using the dynamic
keyword.
For example, if I want to write a function to double a number, I don't care if that number is an int
or a double
as the code will be the same: return value * 2;
.
My best approximation of this would be using dynamic
to simply resolve types at runtime and using a switch
statement to filter types via pattern matching
static void Main(string[] args)
{
double numberD = DoubleNumber(Math.PI);
float numberF = DoubleNumber((float)Math.PI);
int numberI = DoubleNumber((int)Math.PI);
}
static T DoubleNumber<T>(T value)
{
return value switch
{
int or float or double => (dynamic)value * 2,
_ => throw new InvalidCastException(typeof(T).ToString()),
};
}
However, this is still jank since at compile time, literally any type could be sent as input to this function. If a string
is passed into the function, that will not be caught until runtime.
Is there a way to rewrite my function signature such that it will only take int
, uint
, float
, or double
, without copy/pasting the backing code into separate functions targeting these types individually?