15

Is there a way to store an operator inside a variable? I want to do something like this (pseudo code):

void MyLoop(int start, int finish, operator op)
{
    for(var i = start; i < finish; op)
    {
        //do stuff with i
    }
}

I could then call this method like so:

MyLoop(15, 45, ++);
MyLoop(60, 10, --);

Does something like this exist in C#?

JMK
  • 27,273
  • 52
  • 163
  • 280
  • [Possible duplicate](http://stackoverflow.com/q/1190062/1220971) ? – Bridge Jan 10 '13 at 10:25
  • dont know, but do the same with an increment parameter +1 or -1. Or with a lambda Func and your loop will looks like: (int i = start; i < finish; i = op(i)). – tschmit007 Jan 10 '13 at 10:26

5 Answers5

28

I suppose something like this. You do not define the operator, but a function (lambda) which does the change for you.

void MyLoop(int start, int finish, Func<int, int> op)
{
    for(var i = start; i < finish; i = op(i))
    {
        //do stuff with i
    }
}

I could then call this method like so:

MyLoop(15, 45, x => x+1);
MyLoop(60, 10, x => x-1);
Maarten
  • 22,527
  • 3
  • 47
  • 68
10

Use a Function delegate;

Encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter.

void MyLoop(int start, int finish, Func<int, int> op)
{
    for(var i = start; i < finish; i = op(i))
    {
        //do stuff with i
    }
}

Then;

MyLoop(15, 45, x => ++x);
MyLoop(60, 10, x => --x);

Here is a DEMO.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
2

I tried a different approach, using a class that defines operators and accessing via reflection - i.e. you can store your operators as strings. This allows for relational operators as well.

class Program
{
    static void Main(string[] args)
    {
        Operators ops = new Operators();
        object result = ops.Use("LessOrEqual", new object[] {3,2}); // output: False
        Console.WriteLine(result.ToString());

        result =  ops.Use("Increment", new object[] {3}); // output: 4
        Console.WriteLine(result.ToString());
        Console.ReadKey();
    }
}

public class Operators
{
    public object Use(String methodName, Object[] parameters)
    {
        object result;
        MethodInfo mInfo = this.GetType().GetMethod(methodName);
        result = mInfo.Invoke(this, parameters); // params for operator, komma-divided
        return result;
    }


    public bool LessOrEqual(int a, int b)
    {
        if (a <= b)
        {
            return true;
        }
        else
        {
            return false; 
        }  
    }

    public int Increment(int a)
    {
        return ++a;
    }
}
user947737
  • 326
  • 2
  • 11
0

use something like Func<int, int> op

or change the type of op to string, then check the value and according to it build your for loop like:

void MyLoop(int start, int finish, string op)
{
    if ((op.Equals("++") && (start < finish))
    {
      for(var i = start; i < finish; i++)
      {
          //processMethod(i)
      }
    }
    else if ((op.Equals("--") && (start > finish))
    {
      for(var i = start; i < finish; i--)
      {
          //processMethod(i)
      }
    }
}
CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
0
public class Program {
    public static void Main(String[] args) {
        Looper(x => x + 1);
        Looper(x => ++x);
        //Looper(x => x++); will not works
        Looper(x => x * 2);
    }

    public static void Looper(Func<int, int> op) {
        for (int i = 1; i < 10; i = op(i)) {
            Console.WriteLine(i);
        }
        Console.WriteLine("----------");
    }

} 
tschmit007
  • 7,559
  • 2
  • 35
  • 43