Самый эффективный способ объединить два объекта в C # - PullRequest
4 голосов
/ 22 марта 2010

У меня есть два объекта, которые могут быть представлены как int, float, bool или string.Мне нужно выполнить сложение на этих двух объектах так, чтобы результаты были такими же, как и результат c # в результате.Например, 1+ "Foo" будет равно строке "1Foo", 2 + 2.5 будет равно float 5.5, а 3 + 3 будет равно int 6.В настоящее время я использую код ниже, но это кажется невероятным излишним.Может кто-нибудь упростить или указать мне на какой-то способ сделать это эффективно?

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;
}

Ответы [ 2 ]

8 голосов
/ 22 марта 2010

Можете ли вы использовать .NET 4.0? Если это так, то с помощью динамической типизации становится очень просто:

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

Другая альтернатива - иметь карту делегатов для каждой пары возможных типов. К сожалению, до .NET 4.0 не было типа Tuple, поэтому вам придется определить свой собственный тип TypePair в качестве ключа карты. Конечно, вам нужно убедиться, что вы охватили каждую возможную пару ... но по крайней мере компилятор может помочь, когда у вас есть подходящий метод "AddDelegate":

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);
...

Кстати, я взял bool из этого, поскольку «сложение» между bool и float (например) не имеет никакого смысла. Вы можете решить, как вы хотите их объединить.

Хотя, как говорит Митч, я бы пересмотрел ваши дизайнерские решения - вы уверены, что действительно это нужно? Это довольно странное требование. Можете ли вы рассказать нам что-нибудь о большей картине? Мы можем предложить альтернативные подходы.

5 голосов
/ 23 марта 2010

Вы можете просто перегружать метод различными типами, которые вы хотите использовать. Это безопасно для типов и просто.

    private string Combine(string o1, string o2) { return o1 + o2; }
    private string Combine(string o1, int o2) { return o1 + o2; }
    private string Combine(string o1, float o2) { return o1 + o2; }
    private string Combine(float o1, string o2) { return o1 + o2; }
    private float Combine(float o1, int o2) { return o1 + o2; }
    private float Combine(float o1, float o2) { return o1 + o2; }
    private string Combine(int o1, string o2) { return o1 + o2; }
    private float Combine(int o1, float o2) { return o1 + o2; }
    private int Combine(int o1, int o2) { return o1 + o2; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...