Is there a way to parameterize an operator in C #

Say I have 2 increment_click and decment_click handlers, which calls a generic method

In reality, my method can be much more complicated, and I would like to avoid using syntax, for example, if

if (operator == "+") { return value = value + step } else { return value = value - step } 

and do something more general like this

 increment(value, operator, step) { return value = value <operator> step } 

How is this possible?

+4
source share
4 answers

You can make Dictionary<string,Func<decimal,decimal,decimal>> and configure it using the implementations of your operators, for example:

 private static readonly IDictionary<string,Func<decimal,decimal,decimal>> ops = new Dictionary<string,Func<decimal,decimal,decimal>> { {"+", (a,b) => a + b} , {"-", (a,b) => a - b} , {"*", (a,b) => a * b} , {"/", (a,b) => a / b} }; 

Now you can do this:

 decimal Calculate(string op, decimal a, decimal b) { return ops[op](a, b); } 

You can even do this altogether with some kind of β€œmagic” from Linq.Expressions : instead of using the pre-built lambdas defined in C #, you can programmatically define your lambdas and compile them into Func<T,T,T> .

+11
source

I don’t think it’s much better, but it’s a good option.

 int sign = (operator == "+" ? 1 : -1); retrun value +sign*value; 
+2
source

I'm not sure what all of your use case is, but it seems like a suitable scenario for using delegates. Let's start by defining a delegate:

 public delegate T Operation<T>(T arg, T step); 

and now suppose you have a class with operators:

 public class Foo { public static Foo operator + (Foo left, Foo right) { ... } public static Foo operator + (Foo left, Foo right) { ... } } 

In a class where you want to completely process the logic, you can use similar code:

 public class Bar { // The method you look for: public Foo Increment(Foo value, string @operator, Foo step) { Operation<Foo> operation = null; switch(@operator) { case "+": operation = (v, s) => v + s; break; case "-": operation = (v, s) => v - s; break; ... } if (operation != null) { return operation(value, step); } else { throw new NotSupportedException( "Operator '" + @operator "' is not supported"); } } } 

Instead of the Foo class that I used for clarity, you can use any of the primitive types in .NET that support these operations ( int , double , long , etc.).
Instead of defining your own delegate (e.g. Operation<T> , you can use buil-in Func<T, T> .
I would recommend using an enumeration instead of a string for the operators ( + , - , ...), since the string will allow you to pass an invalid value.

+2
source

No, you can only parameterize variables and generalize types.

+1
source

Source: https://habr.com/ru/post/1485317/


All Articles