19

I'm trying to figure out a way to build a conditional dynamically.

Here is my code so far:

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

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

I did read this post, but could not figure out how to implement some of the stuff: C# convert a string for use in a logical condition

Any advice is highly appreciated. Thanks.

mfluehr
  • 2,832
  • 2
  • 23
  • 31
Eric Herlitz
  • 25,354
  • 27
  • 113
  • 157
  • Which part are you having problems with? The accepted answer *seems* straightforward. – ChrisF Aug 16 '11 at 22:56
  • You can consider using an expression evaluator: http://stackoverflow.com/questions/1437964/best-and-shortest-way-to-evaluate-mathematical-expressions – eulerfx Aug 16 '11 at 22:57

3 Answers3

24

I wasn't going to post it, but thought that it might be of some help. Assuming of course that you don't need the advanced generic logic in Jon's post.

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

You could use the code like this, with greaterThan being a string with the wanted logic/operator.

if (greaterThan.Operator(a, b))
eandersson
  • 25,781
  • 8
  • 89
  • 110
16

You can't really do that. The closest you could come would be:

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

and then:

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

The tricky bit is what ConvertToBinaryConditionOperator would do. You might want to look at Marc Gravell's work on implementing generic operators in MiscUtil. Expression trees could be really useful in this case, although I believe Marc has a working approach which works on .NET 2 as well.

So in this case you might have something like (using 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");
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
8

A more generic way of doing it is to take any IComparable objects.

    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);
        }
    }
Benbob
  • 13,876
  • 18
  • 79
  • 114