Преобразовать строковое значение в оператор в C # - PullRequest
12 голосов
/ 17 августа 2011

Я пытаюсь найти способ динамического построения условного выражения.

В примере

var greaterThan = ">";
var a = 1;
var b = 2;

if(a Convert.ToOperator(greaterThan) b) {...}

Я прочитал этот пост, но не мог понять, как реализовать некоторые вещи, C # преобразовать строку для использования в логическом условии

Совет Ано высоко ценится

Спасибо

Ответы [ 3 ]

16 голосов
/ 17 августа 2011

Я не собирался его публиковать, но подумал, что это может помочь.Предполагая, конечно, что вам не нужна расширенная общая логика в посте Джона.

public static class Extension
{
    public static Boolean Operator(this string logic, int x, int y)
    {
        switch (logic)
        {
            case ">": return x > y;
            case "<": return x < y;
            case "==": return x == y;
            default: throw new Exception("invalid logic");
        }
    }
}

Вы можете использовать код, подобный этому, с greaterThan, являющимся string с требуемой логикой / оператором.

if (greaterThan.Operator(a, b))
14 голосов
/ 17 августа 2011

Вы не можете этого сделать.Самое близкое, что вы могли бы получить, это:

Func<T, T, bool> ConvertToBinaryConditionOperator<T>(string op)

, а затем:

if (ConvertToBinaryConditionOperator<int>(input)(a, b))
{
}

Хитрый бит - это то, что сделает ConvertToBinaryConditionOperator.Возможно, вы захотите взглянуть на работу Марка Гравелла по реализации универсальных операторов в MiscUtil .Деревья выражений могут быть действительно полезны в этом случае, хотя я считаю, что у Марка есть рабочий подход, который работает и в .NET 2.

Так что в этом случае у вас может быть что-то вроде (используя MiscUtil )

public static Func<T, T, bool> ConvertToBinaryConditionOperator<T>(string op)
{
    switch (op)
    {
        case "<": return Operator.LessThan<T>;
        case ">": return Operator.GreaterThan<T>;
        case "==": return Operator.Equal<T>;
        case "<=": return Operator.LessThanOrEqual<T>;
        // etc
        default: throw new ArgumentException("op");
    }
}
5 голосов
/ 19 июня 2013

Более общий способ сделать это - взять любые объекты IComparable.

    public static bool Compare<T>(string op, T left, T right) where T : IComparable<T> {
        switch (op) {
            case "<": return left.CompareTo(right) < 0;
            case ">": return left.CompareTo(right) > 0;
            case "<=": return left.CompareTo(right) <= 0;
            case ">=": return left.CompareTo(right) >= 0;
            case "==": return left.Equals(right);
            case "!=": return !left.Equals(right);
            default: throw new ArgumentException("Invalid comparison operator: {0}", op);
        }
    }
...