Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Two Numbers Without Knowing Their Type in .NET?

Tags:

.net

How do I add two numbers together when I don't know their type in .NET? For example, how would you implement the following function?

public object AddTwoNumbers(object left, object right)
{
    /* What goes here? */
}

Assume that the 'left' and 'right' parameters are (boxed) value type such as Int32, double, Decimal, etc. You don't know the specific type, you just know that it's numeric and that addition makes sense for it.

Thanks!

like image 647
user144051 Avatar asked Aug 01 '09 14:08

user144051


2 Answers

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));
    }
}
like image 57
Jon Skeet Avatar answered Oct 21 '22 10:10

Jon Skeet


You can't add anything that you don't know the type of, even if you are certain that it's possible to add them. You have to convert them to a specific type. To be safe from overflows you can convert both to Double as it can handle the range of the other types:

public object AddTwoNumbers(object left, object right) {
   return Convert.ToDouble(left) + Convert.ToDouble(right);
}

However, that doesn't guarantee the precision of the numbers.

You can create overloaded methods to handle different types:

public int AddTwoNumbers(int left, int right) {
   return left + right;
}

public double AddTwoNumbers(double left, double right) {
   return left + right;
}

That of course requires that the type is known at compile time, and doesn't add anything over the + operator.

If neither of those do what you want, I guess that you have to write a lot of if statements checking the type of the arguments to do the correct casting:

public object AddTwoNumbers(object left, object right) {
   if (left is int && right is int) {
      return (int)left + (int)right;
   } else if (left is double && right is duble) {
      return (double)left + (double)right;
   } else ...
      ...
   } else {
      throw new ArgumentException("Arguments could not be added.");
   }
}
like image 35
Guffa Avatar answered Oct 21 '22 09:10

Guffa