繁体   English   中英

C#中的goto及其用法

[英]goto in c# and its usage

我有一个子程序。 它补偿值是否为空然后执行某些操作。 例如,如果它们为空,则会发出警告。 该代码工作正常。 但是,当值不为空时,警告仍会弹出。 请帮助我纠正逻辑。

谢谢。

private void btnNew_Click(object sender, EventArgs e)
    {
        try
        {
            if (txtbox1.Text.ToString().Trim() == string.Empty)
            {
                goto Msg1;
            }
            if (txtbox2.Text.ToString().Trim() == string.Empty)
            {
                goto Msg2;
            }
            DataRow dr = mydataSet.Tables[0].NewRow();
            dr["Descript"] = txtbox1.Text;
            dr["Abbr"] = txtbox2.Text;
            dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
            if (SortOrders.Contains((decimal)dr["SortOrder"]))
            {
                goto Msg3;
            }
            mydataSet.Tables[0].Rows.Add(dr);
            dgv.DataSource = mydataSet.Tables[0];
        Msg1:
            MessageBox.Show("Description is required.");
        Msg2:
            MessageBox.Show("Abbr is required.");
        Msg3:
            MessageBox.Show("Please select another one, this one is already used.");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

从上面的代码中,您将看到。 如果txtbox1具有某些值,程序仍显示Msg1。 我想避免它。

因为标签只是标签,所以标签之后的代码将顺序执行。

您为什么不能这样做:

    try
    {
        if (txtbox1.Text.ToString().Trim() == string.Empty)
        {
            MessageBox.Show("Description is required.");
            return;
        }
        if (txtbox2.Text.ToString().Trim() == string.Empty)
        {
            MessageBox.Show("Abbr is required.");
            return;
        }
        DataRow dr = mydataSet.Tables[0].NewRow();
        dr["Descript"] = txtbox1.Text;
        dr["Abbr"] = txtbox2.Text;
        dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
        if (SortOrders.Contains((decimal)dr["SortOrder"]))
        {
            MessageBox.Show("Please select another one, this one is already used.");
            return;
        }
        mydataSet.Tables[0].Rows.Add(dr);
        dgv.DataSource = mydataSet.Tables[0];
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

它更具可读性。

重组代码以避免goto这是一个遗物,在面向对象的适当代码库中用处不大。

从该方法返回,引发异常或构建错误字典都是比使用goto更好的选择。

例如,您可能有一个List<string> errors ,当您遇到错误情况时,该错误会添加到该错误中。

如果为空,则没有遇到错误,如果没有,则为错误。

这是一个很好的案例,说明goto是错误的方法。 使用类似这样的东西。

private void btnNew_Click(object sender, EventArgs e)
{
    try
    {
        bool error = false;
        if (txtbox1.Text.ToString().Trim() == string.Empty)
        {
            MessageBox.Show("Description is required.");
            error = true;
        }
        if (txtbox2.Text.ToString().Trim() == string.Empty)
        {
            MessageBox.Show("Abbr is required.");
            error = true;
        }
        if (SortOrders.Contains(Convert.ToDecimal(numericOrder.Value)
        {
            MessageBox.Show("Please select another one, this one is already used.");
            error = true;
        }

        if(error)
            return;

        DataRow dr = mydataSet.Tables[0].NewRow();
        dr["Descript"] = txtbox1.Text;
        dr["Abbr"] = txtbox2.Text;
        dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
        mydataSet.Tables[0].Rows.Add(dr);
        dgv.DataSource = mydataSet.Tables[0];
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

编辑

只是发现我的代码实际上与他的第一个示例并没有做相同的事情,因为无论出现多少错误,它都只显示第一个错误。 更新了我的示例以适应该要求。

一直以来,我一直被教导要避免像鼠疫那样去goto,这是我多年以来一直遵循的做法。 在编写代码时,我什至从未考虑过将它作为一种选择。

不过,考虑一下,几年前我确实读过一篇文章(现在找不到),该文章说,只有当您使用gotos跳下代码而不是上跳代码时,您才可以可靠地使用gotos:这是一条坚持的规则这里。

在此处查看更多信息: 仍然有人在C#中使用[goto]吗?为什么?

有更好的方法使用goto语句,例如,使用“返回”(在方法中间使用),“中断”和“继续”的instacne。 您曾经使用其中之一吗?

private void btnNew_Click(object sender, EventArgs e)
{
    try
    {
        var description = txtbox1.Text.Trim();
        if (string.IsNullOrEmpty(description))
        {
            MessageBox.Show("Description is required.");
            return;
        }
        var abbr = txtbox2.Text.Trim();
        if (string.IsNullOrEmpty(abbr))
        {
            MessageBox.Show("Abbr is required.");
            return;
        }
        var numericOrderValue = Convert.ToDecimal(numericOrder.Value);
        if (SortOrders.Contains(numericOrderValue)
        {
            MessageBox.Show("Please select another one, this one is already used.");
            return;
        }

        DataRow dr = mydataSet.Tables[0].NewRow();
        dr["Descript"] = description;
        dr["Abbr"] = abbr;          
        dr["SortOrder"] = numericOrderValue;            
        mydataSet.Tables[0].Rows.Add(dr);
        dgv.DataSource = mydataSet.Tables[0];
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}
private void btnNew_Click(object sender, EventArgs e)
    {
        try
        {
            if (txtbox1.Text.ToString().Trim() == string.Empty)
            {
                MessageBox.Show("Description is required.");
            }
            if (txtbox2.Text.ToString().Trim() == string.Empty)
            {
                MessageBox.Show("Abbr is required.");
            }
            DataRow dr = mydataSet.Tables[0].NewRow();
            dr["Descript"] = txtbox1.Text;
            dr["Abbr"] = txtbox2.Text;
            dr["SortOrder"] = Convert.ToDecimal(numericOrder.Value);
            if (SortOrders.Contains((decimal)dr["SortOrder"]))
            {
               MessageBox.Show("Please select another one, this one is already used.");
            }
            mydataSet.Tables[0].Rows.Add(dr);
            dgv.DataSource = mydataSet.Tables[0];

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

尝试这个。 有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM