I have a generic method which serialises some numeric config entries. Additionally, only for floating point types it must store culture info along. How can I tell that template param is of floating point type?
Here's what I tried:
public void Bar<T>() where T : System.Numerics.INumber<T> {
T aa = default(T);
// this is ugly
if (aa is float || aa is double)
{
}
// error: The type 'T' cannot be used as type parameter 'TSelf' in the generic type
// or method 'IFloatingPoint<TSelf>'. There is no boxing conversion or type parameter
// conversion from 'T' to 'System.Numerics.IFloatingPoint<T>'.
if (aa is IFloatingPoint<T>)
{
}
// works fine and IFloatingPoint<T> would also work if T was constrained to
// IFloatingPoint<T> (but I need to accept also integer types)
if (aa is INumber<T>)
{
}
}
Can I somehow rephrase aa is IFloatingPoint<T>
expression (or use something similar) to make it work and gracefully check T
against being of floating-point-like? Similarly to C++'s
if constexpr (std::is_floating_point_v<T>) {
}
As an alternative to the answer provided by Sweeper, and since you mention the is_floating_point
function from C++, you can replicate that functionality like this:
public bool IsFloatingPoint<T>()
{
return typeof(T)
.GetInterfaces()
.Any(i => i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IFloatingPoint<>));
}
And now in your Bar
method:
public void Bar<T>()
where T : System.Numerics.INumber<T>
{
if (IsFloatingPoint<T>())
{
// Do the floating point stuff
}
}