Is it possible to template methods for any kind of integer size ?
To illustrate, imagine this very trivial example (the body of the method is not important in my question):
public int Mul(int a, int b) {
return a*b;
}
Now, I want the same method that supports any kind of integer (excluding BigInteger of course). I have to write all variants :
public long Mul(long a, long b) {
return a*b;
}
public ulong Mul(ulong a, ulong b) {
return a*b;
}
public short Mul(short a, short b) {
return a*b;
}
public ushort Mul(ushort a, ushort b) {
return a*b;
}
public byte Mul(byte a, byte b) {
return a*b;
}
While this example is very trivial and it's not actually a problem to duplicate, if I have more complex algorithms like this (replicate for all integer kinds):
public static IEnumerable<long> GetPrimesFactors(this long number)
{
for (long i = 2; i <= number / 2; i++)
{
while (number % i == 0)
{
yield return i;
number /= i;
}
}
yield return number;
}
it introduces a maintenance risk as there is duplicated code and logic (coding integrists would say this is the evil to have same logic at multiple place).
Some of you may suggest to implements the long version and cast the result, but having to ask consumer code to cast can be confusing and reduce readability :
void SomeMethod(IEnumerable<int> valuesToProcess)
{
foreach(int value in valuesToProcess) { Console.WriteLine(value); }
}
void Main()
{
int i = 42;
SomeMethod(((long)i).GetPrimesFactors().Select(l=>(int)l));
SomeMethod(GetPrimesFactors(i));
long l = 42L;
SomeMethod(l.GetPrimesFactors().Select(l=>(int)l));
}
When I see the definition of the interface IEnumerable<T>, and especially the definitions of Sum method overloads :
public static decimal? Sum(this IEnumerable<decimal?> source);
public static decimal Sum(this IEnumerable<decimal> source);
public static double? Sum(this IEnumerable<double?> source);
public static double Sum(this IEnumerable<double> source);
public static float? Sum(this IEnumerable<float?> source);
public static float Sum(this IEnumerable<float> source);
public static int? Sum(this IEnumerable<int?> source);
public static int Sum(this IEnumerable<int> source);
public static long? Sum(this IEnumerable<long?> source);
public static long Sum(this IEnumerable<long> source);
I conclude that it's not possible... that's why MS has to implement all overloads.
Does anyone have any tips for designing general purpose integer methods without having to duplicate logic ?