c#:不是所有的代码路径都返回值和不可访问的代码

本文关键字:代码 返回值 访问 路径 | 更新日期: 2023-09-27 18:04:47

嘿,所以我有这个代码,我检查,看看玩家是否可以从他们的库存中删除一个"项目"。'Inventory'是一个排序字典(Item, int)(子问题:我是否需要一个排序字典才能访问索引号中的项目??),而Item是一个类。

     public bool CanRemoveFromItemInventory(string item)
    {
        bool temp = false;
        if (ItemInventory.Count() <= 0)
        {
            return false;
        }
        else if (ItemInventory.Count() > 0)
        {
            for (int b = 0; b < ItemInventory.Count(); b++)
            {
                Item i = ItemInventory.Keys.ElementAt(b);
                if (i.GetName().Equals(item) && ItemInventory[i] >= 1)
                {
                    temp = true;
                }
                else
                {
                    temp = false;
                }
                if (!temp)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
        else
        {
            return temp;
         }
    }

c#:不是所有的代码路径都返回值和不可访问的代码

编译器并不试图理解逻辑——它只是应用规则。就for循环而言,有可能执行 0次,因此中间块缺少返回值:

    else if (ItemInventory.Count() > 0)
    {
        for (int b = 0; b < ItemInventory.Count(); b++)
        {
              // ... this always returns something
        }
        // BUT STILL NEED TO EITHER RETURN OR THROW HERE
    }

实际上,这是正确的-因为一个邪恶的不满者可以编写一个Count()方法,使每次调用返回不同的值(或者呈现一个不那么邪恶的场景-线程竞争/数据突变)。

也许最简单的"修复"就是修改:

    else
    {
        return temp;
    }

:

    return temp;

则适用于所有的分支

将返回值置于for循环之外:

for (int b = 0; b < ItemInventory.Count(); b++) {
     Item i = ItemInventory.Keys.ElementAt(b);
     if (i.GetName().Equals(item) && ItemInventory[i] >= 1) {
         temp = true;
         break;
     }
}
return temp;

推理:如果Count()为0,for循环永远不会被执行,因此你永远不会运行。虽然这可能不太可能(毕竟,您之前检查过Count是否大于0)。编译器无法确定这一点,因为Count()可以在if检查和for循环之间被修改。编译器无法确定这一点(参见"停机问题")

编译器注意到for循环后没有return语句。编译器无法证明代码路径永远不会离开(甚至进入)for循环,因此它期望在循环后的某个时候遇到return语句。但是,在该路径上没有return语句。

对于不可达代码错误,您需要在它抱怨的那一行添加注释。


更新:看起来你要这样做:

public bool CanRemoveFromItemInventory(string item)
{
    var pair = ItemInventory.FirstOrDefault(pair => pair.Key.GetName() == item);
    return pair != null && pair.Value >= 1;
}

如果库存列表中的第一个项目不是您正在搜索的项目,则当前版本的代码将失败。换句话说,即使您修复了编译器错误,您的代码仍然不能正常运行。