C#:if/else的第一个语句起作用,其他语句则不起作用。
C#:if/else的第一个语句起作用,其他语句则不起作用。
我知道这可能非常基础,并且我已经通过搜索引擎进行了搜索,但我遇到了一个非常基本的if/else情况。第一个语句产生了结果,这告诉我其他语句出了问题。这让我有点疯狂。顺便说一下,这是我第一次使用表单窗口的经验。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Wk2_Part1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { int season; int job; season = Convert.ToInt32(textBox1.Text); job = Convert.ToInt32(textBox2.Text); if (season == 1) if (job == 1) label3.Text = "There is a 20% discount on the exterior job"; else if (season == 2) if (job == 1) label3.Text = "There is a 20% discount on the exterior job"; else if (season == 3) if (job == 2) label3.Text = "There is a 30% discount on the interior job"; else label3.Text = "No discount, regular prices apply"; } } }
C#不是Python。在if
语句后面排列else
语句并不会让else
语句和那个if
相关联。如果你不想让if
语句和之后的else
语句发生关联,你需要使用大括号({
和}
)来围绕一个代码块。你也需要确保在一个if
语句的内部条件没有被满足时仍然设置Text
属性。
我还会修改你的逻辑以使你不必重复代码:
if ((season == 1 || season == 2) && job == 1) label3.Text = "There is a 20% discount on the exterior job"; else if (season == 3 && job == 2) label3.Text = "There is a 30% discount on the interior job"; else label3.Text = "No discount, regular prices apply";
当然,以上的代码中我没有使用大括号,尽管我在你的原始代码中说过你需要用它们。实际上,我个人更喜欢总是使用大括号,但以上的代码更符合你原始的格式。
两者的区别在于大括号指定了一组C#语句,这些语句被视为一个单一的语句,目的是控制流程语句,如if
、else
、for
、while
等。通过使用大括号来修复你的原始代码需要将内部的if (job ==1)
部分放在大括号内,而将else
放在大括号外。这样,这个内部的if
语句将被包括在大括号定义的整个块中,而无法与随后的else
语句匹配(因为分支/循环语句不能跨越由大括号定义的代码块)。
以上代码中没有内部的if
语句,只有在if
条件为true
时执行的单个语句。所以随后的else
会正确地与最近的符合要求的if
语句匹配。
大括号可以在其他情况下使用,即使不是严格必需的。许多人,包括我自己在内,认为在每个控制流程语句之后使用它们更好,以定义由该语句控制的块,即使不需要。
这样做的原因是为了避免你遇到的问题。通过明确指定哪些代码块与哪些流程控制相关联,你可以避免这样的问题。注意,这不仅仅是对初学者程序员。即使有经验的程序员也可能会意外地创建类似你所做的漏洞。通常发生的原因不同:代码最初只有一个无大括号的语句,但在以后的某个时候,有人需要修改代码以添加一些逻辑。当他们这样做时,他们未能注意到代码的结构,并打破了预期的流程控制逻辑。有时只是一个语句在流程控制之外,有时更像你的情况,else
标签与错误的if
相关联。无论哪种情况,这都是不好的消息,很容易通过始终包括大括号来避免。
如果我将你的代码块与编译器查看它的方式对齐,它会如下所示。在下面的代码中,您可以看到由于您的if
块没有明确的开始和结束括号,因此else
块与最近的先前if
紧密耦合。正如Peter所说,在C#中的空格不像在Python中那样重要。
private void button1_Click(object sender, EventArgs e) { int season; int job; season = Convert.ToInt32(textBox1.Text); job = Convert.ToInt32(textBox2.Text); if (season == 1) if (job == 1) label3.Text = "There is a 20% discount on the exterior job"; else if (season == 2) if (job == 1) label3.Text = "There is a 20% discount on the exterior job"; else if (season == 3) if (job == 2) label3.Text = "There is a 30% discount on the interior job"; else label3.Text = "No discount, regular prices apply"; }
现在我们可以添加一些大括号来解决这个问题。
private void button1_Click(object sender, EventArgs e) { int season; int job; season = Convert.ToInt32(textBox1.Text); job = Convert.ToInt32(textBox2.Text); if (season == 1) { if (job == 1) { label3.Text = "There is a 20% discount on the exterior job"; } } else { if (season == 2) { if (job == 1) { label3.Text = "There is a 20% discount on the exterior job"; } } } else { if (season == 3) { if (job == 2) { label3.Text = "There is a 30% discount on the interior job"; } } } else { label3.Text = "No discount, regular prices apply"; } }
像这样的代码问题有两个方面。其一,它不太可读。其二,它不太可测试。正如Peter所指出的,您可以通过组合一些if语句来轻松减少此代码的复杂性,如下所示。
if ((season == 1 || season == 2) && job == 1) { label3.Text = "There is a 20% discount on the exterior job"; } else if (season == 3 && job == 2) { label3.Text = "There is a 30% discount on the interior job"; } else { label3.Text = "No discount, regular prices apply"; }
虽然这使得代码更容易理解并减少了字符串消息的重复,但我不会就此止步。为了使该代码可测试,我们需要消除它对某个按钮点击事实的依赖,并大概会有一个涉及到的表单组件(label3
)。为此,我们需要将此代码块移动到返回字符串而不是设置字符串的方法中。
private void button1_Click(object sender, EventArgs e) { int season = Convert.ToInt32(textBox1.Text); int job = Convert.ToInt32(textBox2.Text); label3.Text = GetDiscount(season, job); } private String GetDiscount(int season, int job) { if ((season == 1 || season == 2) && job == 1) { return "There is a 20% discount on the exterior job"; } if (season == 3 && job == 2) { return "There is a 30% discount on the interior job"; } return "No discount, regular prices apply"; }
通过这种方式,我们已经将代码从涉及输入和显示数据的表单解耦。我们还通过消除else语句的需要来进一步降低了复杂性。通过从方法返回字符串,我们退出代码块,因为没有必要继续执行if检查。