C# WinAppCalculator 到 WebAppCalculator

C# WinAppCalculator to WebAppCalculator

您好,我对编码很陌生,尤其是在 C# 中,我的项目有问题。我正在寻找使用 c# 在线制作计算器并将其上传到数据库并以 Azure 形式托管。这是我的问题:

我在 Visual Studio 中使用 Web 表单时遇到 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 = "";
    }
}

}

如果你得到 33 作为 3 + 3 的结果那么这表明你在两个字符串(或者可能是一个字符串和一个数字)而不是两个上使用 + 运算符数字,即 + 运算符正在进行字符串连接而不是加法。

如果您对两个数字(intfloatdoubledecimal 等类型)使用 + 运算符,则它会添加如您所料,两个数字在一起。

但是,如果您在

上使用 + 运算符
  • 两个字符串,或
  • 一个字符串和一个实现了 ToString 方法的实例(这意味着几乎所有不是结构的东西,因为 .net 中的所有 classes 都是派生的来自 object,它有一个 ToString 方法)

然后它连接两个字符串,或者字符串和另一个对象的 ToString 方法的 return 值。 (* 见脚注)

我在代码中看不到发生这种情况的地方,但我建议进行一些重构,这样更容易追踪。

这个开关块有很多重复:

    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 的调用都会 return 相同的两个值,无论执行哪个值,因此只调用一次并缓存结果,例如

    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;

这让您的行更短,更容易阅读,更容易发现任何错误,重要的是嵌套括号更少。在长而复杂的代码行中调换括号和逗号,在最好的情况下会导致编译器错误,但如果不是这样,则可能需要花费数小时来调查应用程序行为异常的原因。

我还注意到,整个开关块似乎在 OperandEvent 和 Bequal_Click 方法中重复出现。两者都需要吗?我无法通过查看发布的代码来判断,但我建议您考虑一下。如果你确实需要它,并且它需要在两者中表现相同,那么将它移到它自己的私有方法中,并从 OperandEvent 和 Bequal_Click 方法中调用该方法。

我可以提请您注意软件开发的 Don't Repeat Yourself 原则吗?

OF ALL THE PRINCIPLES OF PROGRAMMING, Don’t Repeat Yourself (DRY) is perhaps one of the most fundamental. The principle was formulated by Andy Hunt and Dave Thomas in The Pragmatic Programmer, and underlies many other well-known software development best practices and design patterns. The developer who learns to recognize duplication, and understands how to eliminate it through appropriate practice and proper abstraction, can produce much cleaner code than one who continuously infects the application with unnecessary repetition.

Duplication Is Waste

Every line of code that goes into an application must be maintained, and is a potential source of future bugs. Duplication needlessly bloats the codebase, resulting in more opportunities for bugs and adding accidental complexity to the system. The bloat that duplication adds to the system also makes it more difficult for developers working with the system to fully understand the entire system, or to be certain that changes made in one location do not also need to be made in other places that duplicate the logic they are working on. DRY requires that “every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

每当您发现自己多次编写或多或少相同的代码块时,您应该问问自己,“我能否将这段代码重构为一个新的、更短的代码行、一个新的可重用方法,或者甚至是一个新 class?"

希望此回答对您有所帮助,祝您学业顺利。

脚注

我所说的关于 + 运算符的行为并不是全部事实,因为 class 可以明确定义 + 和其他运算符在应用于时的行为方式class 的一个实例(这称为运算符重载)。但是你说你是编程新手,这个细节和这个问题没有太大关系,所以暂时不用担心。