Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most efficient way to combine two objects in C#

I have two objects that can be represented as an int, float, bool, or string. I need to perform an addition on these two objects with the results being the same thing c# would produce as a result. For instance 1+"Foo" would equal the string "1Foo", 2+2.5 would equal the float 5.5, and 3+3 would equal the int 6 . Currently I am using the code below but it seems like incredible overkill. Can anyone simplify or point me to some way to do this efficiently?

private object Combine(object o, object o1) {
    float left = 0;
    float right = 0;

    bool isInt = false;

    string l = null;
    string r = null;
    if (o is int) {
        left = (int)o;
        isInt = true;
    }
    else if (o is float) {
        left = (float)o;
    }
    else if (o is bool) {
        l = o.ToString();
    }
    else {
        l = (string)o;
    }

    if (o1 is int) {
        right = (int)o1;
    }
    else if (o is float) {
        right = (float)o1;
        isInt = false;
    }
    else if (o1 is bool) {
        r = o1.ToString();
        isInt = false;
    }
    else {
        r = (string)o1;
        isInt = false;
    }

    object rr;

    if (l == null) {
        if (r == null) {
            rr = left + right;
        }
        else {
            rr = left + r;
        }
    }
    else {
        if (r == null) {
            rr = l + right;
        }
        else {
            rr = l + r;
        }
    }

    if (isInt) {
        return Convert.ToInt32(rr);
    }

    return rr;
}
like image 902
Dested Avatar asked Dec 12 '22 23:12

Dested


1 Answers

Can you use .NET 4.0? If so, it becomes very simple using dynamic typing:

private object Combine(dynamic o, dynamic o1)
{
    // Assumes an appropriate addition operator, found at execution time
    return o + o1;
}

Another alternative is to have a map of delegates for each pair of possible types. It's unfortunate that before .NET 4.0 there's no Tuple type, so you'll have to define your own TypePair type as the map key. Of course you then need to make sure you cover every possible pair... but at least the compiler can help when you've got a suitable "AddDelegate" method:

private void AddDelegate<T1, T2>(Func<T1, T2, object> sumFunction)
{
    // Put the function in the map
    ...
}

AddDelegate<int,int>((x, y) => x + y);
AddDelegate<int,float>((x, y) => x + y);
AddDelegate<int,string>((x, y) => x + y);
AddDelegate<float,int>((x, y) => x + y);
AddDelegate<float,float>((x, y) => x + y);
AddDelegate<float,string>((x, y) => x + y);
...

Btw, I've taken bool out of that as "addition" between a bool and a float (for example) doesn't make any sense. You can decide how you'd want to combine them though.

As Mitch says though, I'd revisit your design decisions - are you sure you really need this? It's a pretty odd requirement. Can you tell us anything about the bigger picture? We may be able to suggest alternative approaches.

like image 177
Jon Skeet Avatar answered Dec 15 '22 12:12

Jon Skeet