In .NET 3.5 and before, the simplest way is probably to test for every type - or rather, every combination of types - that you can handle, cast appropriately and perform the relevant operation. You could try to fetch the appropriate operator with reflection, but that's likely to have some odd corner cases.
In .NET 4.0 and C# 4, this is easy though:
public object AddTwoNumbers(object left, object right)
{
dynamic x = left;
dynamic y = right;
return x + y;
}
If you're willing to have the restriction that left and right must be the same type, it's not too bad:
using System;
using System.Collections.Generic;
public class Test
{
static Dictionary<Type, Func<object, object, object>> Adders =
new Dictionary<Type, Func<object, object, object>>
{
{ typeof(int), (x, y) => (int) x + (int) y },
{ typeof(double), (x, y) => (double) x + (double) y },
{ typeof(decimal), (x, y) => (decimal) x + (decimal) y },
{ typeof(long), (x, y) => (long) x + (long) y },
// etc
};
static object Add(object left, object right)
{
if (left.GetType() != right.GetType())
{
throw new ArgumentException("Types must be the same");
}
Func<object, object, object> adder;
if (!Adders.TryGetValue(left.GetType(), out adder))
{
throw new ArgumentException
("I don't have an adder for that type");
}
return adder(left, right);
}
static void Main()
{
Console.WriteLine(Add(3, 4));
Console.WriteLine(Add(3.5m, 4.2m));
Console.WriteLine(Add(3.5, 4.8));
}
}