Нужна помощь по моему полиморфному калькулятору C # - PullRequest
0 голосов
/ 22 сентября 2019

Как новичок я пытаюсь отточить свои навыки в ОО-программировании, разрабатывая научный калькулятор с графическим интерфейсом на C # winform, подобный тому, который предоставляется в Windows 10 без использования условных выражений .

Проблема в том, что я не могу придумать способ запретить пользователю нажимать операторы дважды.Например, если пользователь нажимает (1) и нажимает (+), и она пытается нажать (x) снова, моя программа должна заменить последний оператор новым, но не помещать новый оператор в мой стек.

Я использую шаблон посетителя для обработки различных задач операндов и операторов:

IVisitor :

public interface IVisitor
{
    void Visit(Operator op);
    void Visit(Operand op);
}

IOperation

public interface IOperation
{
    string GetValue(string value); 

    string ToString();

    void Accept(IVisitor visitor);
}

событие щелчка в графическом интерфейсе пользователя

private void ButtonClick(object sender, EventArgs e)
{
    // Get Operation ob
    IOperation operation = (IOperation)((Button)sender).Tag;

    // Append to the display panel
    textBox_result.Text = operation.GetValue(Calculator.CurrentValue);
    Calculator.SetDisplayValue(textBox_result.Text);

    operation.Accept(Calculator);
    textBox_result.Text = Calculator.Result;
}

Основная логика калькулятора

public class Calculator : IVisitor
{
    public Calculator()
    {
        this.CurrentValue = "0";
        this.Operators = new Stack<Operator>();
        this.Operands = new Stack<Operand>();
        this.Result = "0";
        this.OperationList = new List<string>();
     }

     public string CurrentValue { get; set; }
     public string Result { get; private set; }
     public List<string> OperationList { get; private set; }
     public Stack<Operator> Operators { get; private set; }
     public Stack<Operand> Operands { get; private set;}

     public void Visit(Operator op)
     {
        this.OperationList.Add(this.CurrentValue);
        this.OperationList.Add(op.ToString());
        this.Operands.Push(new Operand(this.CurrentValue));
        this.CurrentValue = "0";
        while (ThereIsHigherOp(op))
        {
            this.Result = this.Operators.Pop().Compute(this.Operands.Pop().GetValue(), this.Operands.Pop().GetValue());
            this.Operands.Push(new Operand(this.Result));
        }
        this.Operators.Push(op);
    }

    public void Visit(Operand op)
    {
        this.Result = this.CurrentValue;
    }

    private bool ThereIsHigherOp(Operator op)
    {
        return this.Operators.Any() &&this.Operators.Peek().Precedence >= op.Precedence; 
    }
}

Эта, казалось бы, простая проблема привела кЯ схожу с ума по дням, так что любой намек был бы признателен, спасибо заранее!

...