Can anyone tell me if there is a way with generics to limit a generic type argument T
to only:
Int16
Int32
Int64
UInt16
UInt32
UInt64
I'm aware of the where
keyword, but can't find an interface for only these types,
Something like:
static bool IntegerFunction<T>(T value) where T : INumeric
There is no way to restrict templates to types, but you can define different actions based on the type. As part of a generic numeric package, I needed a generic class to add two values.
Note that the typeofs are evaluated at compile time, so the if statements would be removed by the compiler. The compiler also removes spurious casts. So Something would resolve in the compiler to
There is no single interface or base class that they all inherit (that is not also inherited by other classes) so the simple answer is no.
I do wonder why this is an issue though. What are you wanting to do inside your IntegerFunction class that can only be done to integers?
Hejlsberg has described the reasons for not implementing the feature in an interview with Bruce Eckel.
I have to admit, though, that I don't know how he thinks his proposed workaround will work. His proposal is to defer arithmetic operations to some other generic class (read the interview!). How does this help? IMHO, not much.
Workaround using policies:
Algorithms:
Usage:
The solution is compile-time safe. CityLizard Framework provides compiled version for .NET 4.0. The file is lib/NETFramework4.0/CityLizard.Policy.dll.
It's also available in Nuget: https://www.nuget.org/packages/CityLizard/. See CityLizard.Policy.I structure.
If all you want is use one numeric type, you could consider creating something similar to an alias in C++ with
using
.So instead of having the very generic
you could have
That might allow you to easily go from
double
toint
or others if needed, but you wouldn't be able to useComputeSomething
withdouble
andint
in the same program.But why not replace all
double
toint
then? Because your method may want to use adouble
whether the input isdouble
orint
. The alias allows you to know exactly which variable uses the dynamic type.There's no constraint for this. It's a real issue for anyone wanting to use generics for numeric calculations.
I'd go further and say we need
Or even
Unfortunately you only have interfaces, base classes and the keywords
struct
(must be value-type),class
(must be reference type) andnew()
(must have default constructor)You could wrap the number in something else (similar to
INullable<T>
) like here on codeproject.You could apply the restriction at runtime (by reflecting for the operators or checking for types) but that does lose the advantage of having the generic in the first place.