开发者

C#: Not all code paths return value and unreachable code?

开发者 https://www.devze.com 2023-03-26 15:12 出处:网络
Hey so i have this code where i check to see if a player can remove an \'Item\' from their inventor开发者_运维知识库y. The \'Inventory\' is a Sorted Dictionary(Item, int) (subquestion: do i NEED a sor

Hey so i have this code where i check to see if a player can remove an 'Item' from their inventor开发者_运维知识库y. The 'Inventory' is a Sorted Dictionary(Item, int) (subquestion: do i NEED a sorted dictionary to be able to access items in it with an index number??), and an Item is a class.

     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;

         }
    }


The compiler doesn't attempt to understand the logic - it just applies the rules. As far as it is concerned, it is possible that the for loop executes zero times, hence the middle block is missing a return value:

    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
    }

indeed, it is correct in this - as an evil malcontent could write a Count() method that returns different values each call (or to present a less evil scenario - a thread race / data mutation).

Perhaps the easiest "fix" here is to change:

    else
    {
        return temp;
    }

to simply:

    return temp;

then it will apply to all the branches.


Put the return outside of the for loop:

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;

Reasoning: If Count() is 0, the for loop would never be executed and thus you would never raturn. While this maybe unlikely (after all, you check that Count is bigger than 0 before). the compiler is unable to determine that, because Count() can be modified between the if-check and the for loop. The compiler is not able to determine this (see the "Halting Problem")


The compiler is noticing that there is no return statement after the for loop. The compiler cannot prove that the code path will never leave (or even enter) the for loop, and so it is expecting to hit a return statement sometime after the loop. However, you have no return statement on that path.

As for the unreachable code error, you will need to add a comment on the line it's complaining about.


Update: It looks like you're going for something like this:

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

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

The current version of your code will fail if the first item in the inventory list is not the item you are searching for. In other words, even if you fix the compiler errors, your code will still not function correctly.

0

精彩评论

暂无评论...
验证码 换一张
取 消