3

I'm new in C# and i'm trying to create a calculator. I'm storing a arithmetic operator in a string is there any way i can use the operator to solve the equation ?

My code :

else if (btn_name == "plus" || btn_name == "minus")
{
    bol = true;
    try
    {
        if (solve == "")
        {
            string num1 = Screen.Text;
            first = float.Parse(num1);
            second = first + second;
            Screen.Text = second.ToString();
            Screen_upper.Text = upper_text + text + " + ";
        }
        else
        {
            second = first (**#I want to use the operator here#**) second;
        }
    }
    catch
    {
        Screen.Text = second.ToString();
        Screen_upper.Text = upper_text + text + " + ";
    }
    solve = "+";
}
Franz Wimmer
  • 1,477
  • 3
  • 20
  • 38
  • There's a utilty which provides generic operators as methods. http://www.yoda.arachsys.com/csharp/genericoperators.html . Hope this will help you figuring out a good solution. Also use Enums instead of string to define all your operations. – vendettamit Feb 14 '16 at 20:26
  • 1
    I deleted my previous comment because I needed to rephrase as it wasn't clear. There are a plethora of ways to approach this. However as far as actually converting it to an operator directly, the answer is "no". [This Post](http://stackoverflow.com/questions/925886/c-sharp-convert-a-string-for-use-in-a-logical-condition) is something that could really help you. It shows two possible approaches, both with relevant results. Custom classes and generics with a logical switch are good ways of approaching it. – Gabe Feb 14 '16 at 21:02

3 Answers3

3

You can use just if or switch operator and branches your logic for each else/case block:

switch(btn_name)
{
    case "plus":
        second = first + minus;
        break;
    case "minus":
        second = first - minus;
        break;
    case "div":
        second = first / minus;
        break;
}

But it's very difficult to read this code. The alternate solution is to to use predefined repository of operators. One way to implement it is to use simple Dictionary<string, Func<float, float, float>> and delegate:

// it's class member, not a local variable 
Dictionary<string, Func<float, float, float>> operators = new Dictionary<string, Func<float, float, float>>();
operators.Add("plus", (first, second) => first + second);
operators.Add("minus", (first, second) => first - second);
operators.Add("div", (first, second) => first / second);

Now you can use next code (completed your example):

if (solve == "")
{
    string num1 = Screen.Text;
    first = float.Parse(num1);
    second = first + second;
    Screen.Text = second.ToString();
    Screen_upper.Text = upper_text + text + " + ";
}
else
{
    second = operators[btn_name](first, second);
}

It can be better because you will split operators initialization and usage and make code bit clear.

Another one scenario is to have different event handler for each button and implement necessary logic inside the handler. But then you will need to refactor your code fore merge duplicated parts (number parsing and updating result) and your final solution will be nearly the same with dictionary based.

Vadim Martynov
  • 8,602
  • 5
  • 31
  • 43
  • This is what I was trying to say but without source code. Just sounded like homework to me. English hard... +1 – Gabe Feb 14 '16 at 21:03
1

No i think you can't. Check value you have in btn_name and if it's "minus" perform arithmetic operation

if (btn_name == "minus")
{
    second = first - second;
}
shx
  • 43
  • 7
1

What I would think is the best way to do it, is to have a dictionary having key as the name of the operation and as the value a delegate, eg

var dict = new Dictionary<string, Func<int, int, int>> () {
    { "add", AddFunc },
    { "minus", MinusFunc }
};

public static int AddFunc(int arg1, int arg2)
{
    return arg1 + arg2;
}

public static int MinusFunc(int arg1, int arg2)
{
    return arg1 - arg2;
}

Calling the methods is as simple as dict["minus"](arg1,arg2)

Of course it would more sense to use Enums instead of strings but you get the idea.

Konstantine
  • 71
  • 1
  • 9