C#:并非所有代码路径都返回值和无法访问的代码?

时间:2011-08-06 22:21:52

标签: c# compiler-errors

嘿所以我有这个代码,我检查一下玩家是否可以从他们的库存中删除'Item'。 'Inventory'是一个Sorted Dictionary(Item,int)(subquestion:我需要一个排序的字典才能访问索引号中的项目吗?),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;

         }
    }

3 个答案:

答案 0 :(得分:6)

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

    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;

然后它将适用于所有分支。

答案 1 :(得分:2)

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

至于无法访问的代码错误,您需要在它抱怨的行上添加注释。


更新:看起来你想要这样的事情:

public bool CanRemoveFromItemInventory(string item)
{
    var pair = ItemInventory.FirstOrDefault(pair => pair.Key.GetName() == item);

    return pair != null && pair.Value >= 1;
}

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

答案 2 :(得分:2)

将回报放在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)。编译器无法确定,因为可以在if-check和for循环之间修改Count()。编译器无法确定这一点(请参阅“Halting Problem”)