Please feel free to offer more clarification if my answer seems off-kilter.
There are no generic constraints on operators in the C# language, at least. As Jon Skeet has proven with Unconstrained Melody, the constraints might actually be perfectly valid in the CLR itself.
The best you can do with constraints is provide interfaces / custom classes that expose the actions you need. You wouldn't be able to provide the primitive (unless you also implement the implicit
operator perhaps), but it would at least let you create generic code for the math part.
Generic constraints allow the compiler to infer the available members based on the lowest common denominator (as specified by the constraint or lack of). Most of the time, generics are unconstrained and thus give you only object
semantics.
Alternatively, avoid using constraints and use
dynamic
to temporarily store the generic variable and then make the assumption (via duck typing) that it has the relevant operators:
class Program
{
static void Main(string[] args)
{
var result = Add<int, long, float>(1, 2);
Console.WriteLine(result); // 3
Console.WriteLine(result.GetType().FullName); // System.Single
Console.Read();
}
static T3 Add<T1, T2, T3>(T1 left, T2 right)
{
dynamic d1 = left;
dynamic d2 = right;
return (T3)(d1 + d2);
}
}
This involves the DLR and will have some performance overhead (I don't have exact figures), especially if you intend the calculations to be performance-critical.
I'm not sure what you mean "declare the same generic type multiple times", this works:
class Tuple<T1, T2> // etc.
var myTuple = new Tuple<int, int>(1, 2);