从For循环返回值

本文关键字:返回值 循环 For | 更新日期: 2023-09-27 18:09:50

我在我的应用程序中有一个listView。我循环遍历项目以检查当前选择的项目,然后返回一个值。由于所有路径都必须返回一个值,我必须在循环外返回一个覆盖for循环返回的值,我如何保持这个而不在循环后覆盖它?

public string GetItemValue()
{
    for (int i = 0; i < listView1.Items.Count; i++)
    {
        if (listView1.Items[i].Checked == true)
        {
            return listView1.Items[i].Text; // I want to keep this value
        }
     }
     // Without overwriting it with this but the compiler 
     // requires me to return a value here
     return "Error"; 
}

任何帮助都是最感激的。谢谢。

p。S我试过在if之后使用break,但没有运气

从For循环返回值

编辑:从上面取出我的评论

你不需要担心这个。一旦它到达循环中的第一个return,它将立即返回该值。在这种情况下,循环外的代码不会被击中。

顺便说一下,下面的代码会更简洁:
public string GetItemValue()
{
    foreach (var item in listView1.Items)
    {
        if (item.Checked) return item.Text;
    }
    throw new InvalidOperationException("No checked items found");
}

异常是一种更习惯的处理错误的方式,当你只是在集合上迭代时,foreach循环比for循环更可取。

同样使用LINQ,你可以得到更简洁的:

public string GetItemValue()
{
    return listView1.Items.Cast<ListViewItem>().Single(i => i.Checked).Text;
}

那么,您的返回在循环之外,return "Error";不应该根据您的逻辑被调用。因为return会导致你的方法立即退出,所以永远不会出现"Error"返回,除非代码永远不会进入循环中的if

考虑到所有因素,这可能是代码中异常的情况。因此,抛出异常可能是合适的做法:
public string GetItemValue()
        {
            for (int i = 0; i < listView1.Items.Count; i++)
            {
                if (listView1.Items[i].Checked == true)
                {
                    return listView1.Items[i].Text; // I want to keep this value
                }
            }
            throw new InvalidOperationException("Did not find value expected.");
        }
通常会抛出异常,表示代码中存在错误。"嘿,这真的不应该发生。"应用程序停止,希望用户有机会联系支持来帮助您重新生成它。

根据你的评论:

当我运行它时,它只是返回错误文本…

这意味着您在if语句中的检查不成功。

if (listView1.Items[i].Checked == true)

这意味着你的ListView中没有一个项目被选中

在这种情况下,您最好抛出异常,以便发出异常情况的信号:

public string GetItemValue()
{
    for (int i = 0; i < listView1.Items.Count; i++)
    {
        if (listView1.Items[i].Checked == true)
        {
            // Here you are leaving the GetItemValue method
            // and the loop stops
            return listView1.Items[i].Text;
        }
    }
    // if we get that far it means that none of the items of
    // the select list was actually checked => we are better of
    // reporting this to the caller of the method
    throw new Exception("Please select a value");
}

for循环中的返回值不会被覆盖——如果满足条件,该方法将返回循环中的值。方法的执行在到达return语句后立即结束。

如果你的方法返回"Error",那么我建议在调试器中查看你的代码,因为它到达循环结束并返回值"Error"

如果你在循环中返回一个值,它不应该到达循环外的返回值。我将检查以确保循环正在查找所选项目。

另一个选择是创建一个局部变量来保存返回值:

string returnValue = "Error";
for (int i = 0; i < listView1.Items.Count; i++) 
{ 
    if (listView1.Items[i].Checked == true) 
    { 
        returnValue = listView1.Items[i].Text;
        break;
    } 
} 
return returnValue;

最后,您还可以考虑在没有找到任何选择时返回一个异常,并从调用方法处理异常。

return "Error"位不会覆盖循环返回值。当点击return时,该函数退出,因此当找到选定的值时,该函数将吐出您的数据并停止。

编译器要求函数的所有路径都返回一个值。编译器无法事先知道内部循环是否满足if条件。你可以将值缓存在变量中,并在函数末尾返回,例如:

public string GetItemValue()
    {
        string temp = null;
        for (int i = 0; i < listView1.Items.Count; i++)
        {
            if (listView1.Items[i].Checked == true)
            {
                temp = listView1.Items[i].Text; // I want to keep this value
                break;
            }
        }
        return temp; // Without overwriting it with this but the compiler requires me to return a value here
    }

实际上,这里不需要循环:

return (listView1.SelectedItems.Count > 0)
    ? listView1.SelectedItems[0].Text
    : "Error";

但是,正如所说,最初的问题是误导性的,因为return不覆盖值。你可能考虑的是任务,而不是回报。在这种情况下,工作代码看起来像这样:

string ret = "Error";
foreach(var item in listView1.Items)
{
    if(item.Checked) { ret = item.Text; break; }
}
return ret;