Как новичок я пытаюсь отточить свои навыки в ОО-программировании, разрабатывая научный калькулятор с графическим интерфейсом на 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;
}
}
Эта, казалось бы, простая проблема привела кЯ схожу с ума по дням, так что любой намек был бы признателен, спасибо заранее!