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;
}
}
编译器并不试图理解逻辑——它只是应用规则。就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;
}
如果库存列表中的第一个项目不是您正在搜索的项目,则当前版本的代码将失败。换句话说,即使您修复了编译器错误,您的代码仍然不能正常运行。