并非所有代码路径都应该返回值

时间:2016-12-05 21:06:06

标签: c# error-handling file-handling

尝试在控制台应用程序中完成库存系统,因此我被困在这一部分,以确保用户不能拥有重复的8位长ID号,我的问题如下。

基本上我不确定为什么这段代码不起作用,我可能在这里错过了一段非常明显的代码,感谢帮助,尝试改变已经存在的值,因此很可能忽略了一个值。< / p>

static int checkIDNumber(int ID)
{
    // Check the number passed in & then loop through all the lines...
    // If number is taken then output error, because id exists already
    // Else allow the value to be used in the stock system.

    int IDNumber = ID;
    using (StreamReader sr = new StreamReader("Stockfile.txt"))
    {
        string lineValues;

        while (sr.EndOfStream == false)
        {
            lineValues = sr.ReadLine();

            if (lineValues.Contains(IDNumber.ToString()))
            {
                Console.WriteLine("Id number is currently already taken.");
            }
            else
            {
                return IDNumber;
            }
        }
    }
}

我在另一个过程中从这一行传入我的值,并在本地范围内定义。

stockID = checkIDNumber(stockID);

以下是完整代码:

class Program
{
    static void Main(string[] args)
    {
        char menuOption = '0';

        while (menuOption != '3')
        {
            DisplayMenuOption();
            menuOption = GetMenuOption();

            switch (menuOption)
            {
                case '1':
                    AddStock();
                    break;

                case '2':
                    CheckStock();
                    break;

                case '3':
                    Console.WriteLine("Goodbye");
                    break;

                default:
                    Console.WriteLine("That is not a valid option");
                    break;

            }
        }


            // Keep it all happy for a screenshot ;)
            Console.ReadLine();

    }

    static void DisplayMenuOption()
    {
        Console.WriteLine("Do you wish to Add Stock(1) or Check Stock(2) or Exit(3)?");
    }

    static void DisplayStockOption()
    {
        Console.WriteLine("Do you want to search by ID(1) or by Name(2), Delete current stock(3) or Exit(4)?");
    }

    static char GetMenuOption()
    {

        char userChoice = '0';

        userChoice = Convert.ToChar(Console.ReadLine());
        return userChoice;
    }

    static void CheckStock()
    {
        char menuOption = 'a';
        while (menuOption != '4')
        {
            DisplayStockOption();
            menuOption = GetMenuOption();

            switch (menuOption)
            {
                case '1':
                    SearchID();
                    break;

                case '2':
                    SearchName();
                    break;

                case '3':
                    RemoveStock();
                    break;

                case '4':
                    Console.WriteLine("Goodbye");
                    break;

                default:
                    Console.WriteLine("That is not a valid option");
                    break;

            }
        }
    }

    static void RemoveStock()
    {
        List<string> tempList = new List<string>();
        string lineValues = "";
        bool found = false;
        int ID = 0;

        using (StreamReader sr = new StreamReader("Stockfile.txt"))
        {

            Console.Write("Please enter the ID number to delete: ");
            ID = Convert.ToInt32(Console.ReadLine());

            while (sr.EndOfStream == false)
            {
                lineValues = sr.ReadLine();

                if (lineValues.Contains(ID.ToString()) == false)
                {
                    tempList.Add(lineValues);
                }
                else
                {
                    found = true;
                }
            }
        }

        if (found == true)
        {
            using (StreamWriter sw = new StreamWriter("Stockfile.txt", false))
            {
                for (int i=0; i < tempList.Count; i++)
                {
                    sw.Write(tempList[i]);
                    sw.WriteLine();
                }
            }
        }
    }

    static void SearchName()
    {
        using (StreamReader sr = new StreamReader("Stockfile.txt"))
        {
            string name;

            Console.Write("Please enter the name: ");
            name = Console.ReadLine();


            while (sr.EndOfStream == false)
            {

                string lineValues = sr.ReadLine();

                if (lineValues.Contains(name))
                {
                    Console.WriteLine("{0}", lineValues);
                }
                else
                {
                    Console.WriteLine("{0} does not exist in this stock system!",name); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match.
                }
            }
        }
   }



        static void SearchID()
    {

        using (StreamReader sr = new StreamReader("Stockfile.txt"))
        {
            int IDNumber;
            string lineValues;

            Console.Write("Please enter the ID number: ");
            IDNumber = Convert.ToInt32(Console.ReadLine());


            while (sr.EndOfStream == false)
            {

                lineValues = sr.ReadLine();

                if (lineValues.Contains(IDNumber.ToString()))
                {
                    Console.WriteLine("{0}", lineValues);
                }
                else
                {
                    Console.WriteLine("{0} does not exist in this stock system!", IDNumber); // Could try to match a similar string incase of spelling errors here, although after looking at it it may be a bit far for what is being required now, but in the real world application this would be a must else people would mistype words thus not having an exact match.
                }
            }
        }
    }

    static int checkIDNumber(int ID)
    {
        // Check the number passed in & then loop through all the lines...
        // If number is taken then output error, becuase id exists already
        // Else allow the value to be used in the stock system.


        using (StreamReader sr = new StreamReader("Stockfile.txt"))
        {
            int IDNumber;
            string lineValues;

            Console.Write("Please enter the ID number: ");
            IDNumber = Convert.ToInt32(Console.ReadLine());


            while (sr.EndOfStream == false)
            {

                lineValues = sr.ReadLine();

                if (lineValues.Contains(IDNumber.ToString()))
                {
                    Console.WriteLine("Id number is currently already taken.");
                }
                else
                {
                    ID = IDNumber;
                    return ID;
                }
            }
        }


    }

    static void AddStock(int IDNumber)
    {

        using (StreamWriter sw = new StreamWriter("Stockfile.txt", true))
        {
            int stockID = 0;
            int stockQuantity = 0;
            double stockPrice = 0.00;
            string stockName = "";
            string s = ""; // Being Lazy here, to convert to when needed.

            while (stockID.ToString().Length != 8)
            {
                Console.Write("Please enter the stock ID number: ");
                stockID = Convert.ToInt32(Console.ReadLine());

            }

            s = stockID.ToString();
            sw.Write(s + "\t"); // Will only accept an 8 figure digit so is safe to have a single value here.

            while (stockName.Length <= 2) // No fancy brands here......
            {
                Console.Write("Please enter the name of the stock: ");
                stockName = Console.ReadLine();
            }

            s = stockName;
            sw.Write(s + "\t");

            while (stockQuantity < 1) // Running a small shop here...
            {
                Console.Write("Please enter the quanity of stock: ");
                stockQuantity = Convert.ToInt32(Console.ReadLine());
            }

            s = stockQuantity.ToString();
            sw.Write(s + "\t");

            while (stockPrice < 0.01) // Running a very small shop....
            {
                Console.Write("Please enter the price of the stock: ");
                stockPrice = Convert.ToDouble(Console.ReadLine());
            }

            s = stockPrice.ToString();
            sw.Write(s + "\t");

            sw.WriteLine(); // TO create the new line.....

        }

    }
}

}

2 个答案:

答案 0 :(得分:7)

问题是你只是从else块中返回一个值。

无论程序通过代码执行哪条路径,您的方法都需要返回一个值。您可以通过多种方式解决此问题,具体取决于您的要求。例如,你可以在方法的底部有一个“catch-all”返回值,这样如果它通过你所有的测试(即if块)并到达底部,只要这是一个有意义的结果,它将返回catch-all值。

或者,您可以确保在每个代码路径中放置return语句。为此,您需要在return区块的if部分添加if,但您可能仍需要在while之外返回因为那可能永远不会执行。

同样,这完全取决于您的需求。

答案 1 :(得分:3)

至少在逻辑上,该文件只包含ID。例如,如果我输入“10”作为ID而文件是:

10
10
10
10
...

情况可能就是你知道实际永远不会发生,但编译器不能证明它不会。从编译器的“视角”来看,“可能发生”和“无法证明它不会发生”之间并没有真正的区别。

另外,你的逻辑错了。如果您知道用户请求了重复的ID,则无需检查文件的其余部分 - 您已经知道它是重复的。

现在,如果文件的第一行不是他们请求的ID,它将允许用户接受它。例如,如果用户请求“9”作为ID,则文件如下:

3 -- It only actually checks this line
5
9 -- Obviously the ID is already taken here but it'll never check this line
2
1

请参阅下面的评论:

// I'd suggest making this "bool" - they already know what the ID number is,
// so there's no point in returning it back to them
static int checkIDNumber(int ID)
{
    // Check the number passed in & then loop through all the lines...
    // If number is taken then output error, because id exists already
    // Else allow the value to be used in the stock system.

    int IDNumber = ID;
    using (StreamReader sr = new StreamReader("Stockfile.txt"))
    {

        string lineValues;

        // In general, you shouldn't explicitly compare to "true" or "false."
        // Just write this as "!sr.EndOfStream"
        while (sr.EndOfStream == false)
        {

            lineValues = sr.ReadLine();

            if (lineValues.Contains(IDNumber.ToString()))
            {
                // In this case, you don't have to bother checking the rest of the file
                // since you already know that the ID is taken
                Console.WriteLine("Id number is currently already taken.");

            }
            else
            {
                // You actually can't return that at this point - you need to check
                // the *entire* file before you conclude that it's not a duplicate
                return IDNumber;
            }
        }

    }
}