嗨,我对编码非常陌生,尤其是在 c# 中,我的项目有问题。我正在寻找使用 c# 在线制作计算器并将其上传到数据库和天蓝色主机。这是我的问题:
我在使用 Web 表单的 Visual Studio 中遇到我的 c# 代码问题。它根本不起作用,它可以输入数字和操作,但是没有得到正确的结果,例如3 + 3 = 33。这是从 WinApp 转换而来的,所以它可能来自那里?但我重新创建了 UI 并重新调整了代码的用途以适应在线应用程序。在我开始工作后,我计划将它上传到 azure。这有什么原因不起作用吗?我在 .NET 中的 WinApp 有一个非常相似的代码并且可以工作,所以它是 .NET/ASP.net 问题吗?任何帮助表示赞赏!
这是 .aspx.cs 文件:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class WebForm1 : Page
{
protected void Page_Load(object sender, EventArgs e)
{
ViewState["operationPerf"] = "false";
ViewState["operation"] = string.Empty;
ViewState["answer"] = "0";
}
protected void NumbEvent(object sender, EventArgs e)
{
if (textbox.Text == "0" || bool.Parse(ViewState["operationPerf"].ToString()) == true)
textbox.Text = string.Empty;
Button butt = (Button)sender;
textbox.Text += butt.Text;
ViewState["operationPerf"] = false;
label.Text = label.Text + " " + textbox.Text;
}
protected void OperandEvent(object sender, EventArgs e)
{
ViewState["operationPerf"] = true;
Button butt = (Button)sender;
string newOperand = butt.Text;
label.Text = label.Text + " " + newOperand;
switch (ViewState["operation"])
{
case "+":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(Double.Parse(Convert.ToString(ViewState["answer"])), Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
ViewState["answer"] = textbox.Text;
ViewState["operation"] = newOperand;
}
protected void Bequal_Click(object sender, EventArgs e)
{
ViewState["operationPerf"] = true;
switch (ViewState["operation"])
{
case "+":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(Double.Parse(Convert.ToString(ViewState["answer"])), Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
label.Text = label.Text + " = " + textbox.Text;
label.Text = "";
ViewState["answer"] = textbox.Text;
textbox.Text = ViewState["answer"].ToString();
ViewState["answer"] = 0;
ViewState["operation"] = "";
}
protected void BC_Click(object sender, EventArgs e)
{
textbox.Text = "0";
label.Text = "";
ViewState["answer"] = 0;
ViewState["operation"] = "";
}
}
这是我尝试解决问题之前的原始代码:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class WebForm1 : Page
{
bool operationPerf = false;
string operation = "";
double answer = 0;
protected void NumbEvent(object sender, EventArgs e)
{
if (textbox.Text == "0" || operationPerf)
textbox.Text = string.Empty;
Button butt = (Button)sender;
textbox.Text += butt.Text;
operationPerf = false;
label.Text = label.Text + " " + textbox.Text;
}
protected void OperandEvent(object sender, EventArgs e)
{
operationPerf = true;
Button butt = (Button)sender;
string newOperand = butt.Text;
label.Text = label.Text + " " + newOperand;
switch (operation)
{
case "+":
textbox.Text = (answer + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (answer - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (answer * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (answer / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(answer, Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
answer = Double.Parse(textbox.Text);
operation = newOperand;
}
protected void Bequal_Click(object sender, EventArgs e)
{
operationPerf = true;
switch (operation)
{
case "+":
textbox.Text = (answer + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (answer - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (answer * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (answer / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(answer, Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
label.Text = label.Text + " = " + textbox.Text;
label.Text = "";
answer = Double.Parse(textbox.Text);
textbox.Text = answer.ToString();
answer = 0;
operation = "";
}
protected void BC_Click(object sender, EventArgs e)
{
textbox.Text = "0";
label.Text = "";
answer = 0;
operation = "";
}
}
}
答案 0 :(得分:1)
如果你得到 33 作为 3 + 3 的结果,那么这表明你在两个字符串(或者一个字符串和一个数字)而不是两个数字上使用 +
运算符,即 +
运算符正在执行字符串连接而不是加法。
如果您对两个数字(类型如 +
、int
、float
、double
)使用 decimal
运算符,然后它将两个数字相加如您所愿。
但是,如果您在
上使用+
运算符
ToString
方法的实现(这意味着几乎所有不是结构体的东西,因为 .net 中的所有类都是从 object
派生的,它有一个 ToString
方法)然后它连接两个字符串,或者字符串和另一个对象的 ToString
方法的返回值。 (* 见脚注)
我无法在代码中看到发生这种情况的地方,但我建议进行一些重构,这样可以更轻松地进行追踪。
这个开关块有相当多的重复:
switch (ViewState["operation"])
{
case "+":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) - Double.Parse(textbox.Text)).ToString();
break;
所有对 Double.Parse 的调用都将返回相同的两个值,无论执行哪个值,因此只调用一次并缓存结果,例如
var answer = Double.Parse(Convert.ToString(ViewState["answer"]));
var textboxValue = Double.Parse(textbox.Text);
switch (ViewState["operation"])
{
case "+":
textbox.Text = (answer + textboxValue).ToString();
break;
case "-":
textbox.Text = (answer - textboxValue).ToString();
break;
这让你的行更短,更容易阅读,更容易发现任何错误,重要的是有更少的嵌套括号。在长而复杂的代码行中转置括号和逗号,在最好的情况下会导致编译器错误,但如果不这样做,则可能需要花费数小时来调查应用程序行为异常的原因。
我还注意到整个 switch 块在 OperandEvent 和 Bequal_Click 方法中似乎都重复了。两者都需要吗?我无法通过查看已发布的代码来判断,但我建议您考虑一下。如果两者都需要它,并且它需要在两者中具有相同的行为,则将其移动到其自己的私有方法中,并从 OperandEvent 和 Bequal_Click 方法中调用该方法。
我可以提请您注意软件开发的 Don't Repeat Yourself 原则吗?
<块引用>在所有编程原则中,不要重复自己 (DRY) 可能是最基本的原则之一。该原则由 Andy Hunt 和 Dave Thomas 在 The Pragmatic Programmer 中阐述,是许多其他知名软件开发最佳实践和设计模式的基础。学会识别重复并了解如何通过适当的实践和适当的抽象来消除重复的开发人员,可以生成比以不必要的重复不断感染应用程序的开发人员更干净的代码。
重复是浪费
进入应用程序的每一行代码都必须维护,并且是未来错误的潜在来源。重复不必要地使代码库膨胀,导致出现更多错误的机会并意外增加系统的复杂性。重复给系统带来的膨胀也使得使用系统的开发人员更难以完全理解整个系统,或者确定在一个位置所做的更改也不需要在重复逻辑的其他地方进行。他们正在努力。 DRY 要求“系统中的每一条知识都必须有一个单一的、明确的、权威的表示。”
每当您发现自己或多或少地多次编写相同的代码块时,您应该问自己,“我可以将此代码重构为一个新的、更短的行、一个新的可重用方法,或者甚至一个新类?”
希望这个答案对您有所帮助,并祝您学业顺利。
我所说的 +
运算符的行为并不是全部事实,因为一个类可以明确定义 +
和其他运算符在应用于该类的实例时的行为方式(这称为运算符重载)。但是你说你是编程新手,这个细节与这个问题并不真正相关,所以现在不要担心。