简体   繁体   English

C# 返回错误“并非所有代码路径都返回值” - 如何找到不返回值的路径

[英]C# returning error “not all code paths return a value” - how to find the path not returning a value

I am very new to programming in general so I may be missing something very obvious.一般来说,我对编程很陌生,所以我可能会遗漏一些非常明显的东西。 But still, which path leads to not returning a value?但是,哪条路径导致不返回值?

public static int CheckAge()
        {
            int userAge; 
            bool inValidInput = true;
            while (inValidInput)
            {
                Console.Write("Enter your age: ");
                string stringAge = Console.ReadLine();

                if (int.TryParse(stringAge, out userAge))
                {
                    switch (userAge)
                    {
                        case int n when (n < 1 || n > 120):
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.Write("RANGE ");
                            Console.ForegroundColor = ConsoleColor.White;
                            Console.Write("error\n");
                            Console.Write("Accepted range are numbers (eg. 123) ");
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.Write("between 1 and 120\n");
                            Console.ForegroundColor = ConsoleColor.White;
                            break;

                        default:
                        return userAge;
                    }
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write("TYPE ");
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write("error\n");
                    Console.Write("Accepted input types are ");
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write("numbers (eg. 123) ");
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write("between 1 and 120\n");
                    continue;  
                }
            }
        }

When I look at it I feel like all paths should EVENTUALLY lead to:当我看到它时,我觉得所有路径最终都应该导致:

default:
   return userAge;

If I need to provide the full source code please let me know and I will add it, did not want to make it to messy in case all I needed was the example.如果我需要提供完整的源代码,请告诉我,我会添加它,不想让它变得混乱,以防我需要的只是示例。

EDIT: I really liked the solution given by @oerkelens but I am struggling to make the userAge variable behave properly.编辑:我真的很喜欢@oerkelens 提供的解决方案,但我正在努力使 userAge 变量表现正常。 Below Using:(return userAge; inside if statement):下面使用:(返回 userAge;在 if 语句中):

public static int CheckAge()
        {
            int userAge;
            bool inputIsValid = false;
            while (!inputIsValid)
            {
                Console.Write("Enter your age: ");
                string stringAge = Console.ReadLine();

                if (!int.TryParse(stringAge, out userAge))
                {
                    WriteNumericalError();
                    continue;
                }

                if (userAge < 1 || userAge > 120)
                {
                    WriteRangeError();
                    continue;
                }

                inputIsValid = true;
                return userAge;
            }
        }

Gives me the good old: 'Program.CheckAge()': not all code paths return a value给了我一个很好的旧:'Program.CheckAge()':并非所有代码路径都返回一个值

Below Using:(return userAge; outside if statement):下面使用:(返回 userAge;在 if 语句之外):

public static int CheckAge()
        {
            int userAge;
            bool inputIsValid = false;
            while (!inputIsValid)
            {
                Console.Write("Enter your age: ");
                string stringAge = Console.ReadLine();

                if (!int.TryParse(stringAge, out userAge))
                {
                    WriteNumericalError();
                    continue;
                }

                if (userAge < 1 || userAge > 120)
                {
                    WriteRangeError();
                    continue;
                }

                inputIsValid = true;
            }
            return userAge;
        }

Solved the 'Program.CheckAge()': not all code paths return a value but introduces: Use of unassigned local variable 'userAge'解决了“Program.CheckAge()”:并非所有代码路径都返回一个值,而是引入了:使用未分配的局部变量“userAge”

FINAL SOLUTION最终解决方案

public static int CheckAge()
        {
            int userAge = 0;
            bool validInput = false;
            while (!validInput)
            {
                Console.Write("Enter your age: ");
                string stringAge = Console.ReadLine();

                if (!int.TryParse(stringAge, out userAge))
                {
                    WriteNumericalError();
                    continue;
                }

                if (userAge < 1 || userAge > 120)
                {
                    WriteRangeError();
                    continue;
                }
                validInput = true;
            }
            return userAge;
        }


        private static void WriteNumericalError()
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.Write("TYPE ");
            Console.ForegroundColor = ConsoleColor.White;
            Console.Write("error\n");
            Console.Write("Accepted input types are numbers ");
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.Write("(eg. 1 2 3 4 5 6 7 8 9 0)\n");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("Press [Enter] to try again");
            Console.ReadLine();
        }

        private static void WriteRangeError()
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("RANGE ");
            Console.ForegroundColor = ConsoleColor.White;
            Console.Write("error\n");
            Console.Write("Your entered number does not fall within the accepted range ");
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("1 to 5 for film choice - 1 to 120 for age input\n");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("Press [Enter] to try again");
            Console.ReadLine();
        }

First, you're using an obscured infinite loop.首先,您正在使用一个模糊的无限循环。 Even as while (true) , this seems like a code smell.即使是while (true) ,这似乎也是一种代码味道。
Secondly, your flag has a negative meaning.其次,您的标志具有负面含义。 That drives people mad.这让人们发疯。 inValidInput == false means the input is valid! inValidInput == false表示输入有效!
Third, it's hard to see what you want to accomplish with your code.第三,很难看出你想用你的代码完成什么。

Below is an example addressing these things.下面是一个解决这些问题的例子。 There are still other possible improvements, but it's a start.还有其他可能的改进,但这是一个开始。

public static int CheckAge()
{
    int userAge = 0; 
    bool inputIsValid = false;
    while (!inputIsValid)
    {
       Console.Write("Enter your age: ");
       string stringAge = Console.ReadLine();

       if (!int.TryParse(stringAge, out userAge))
       {
           WriteNumericalError();
           Continue;
       }
       
       if (userAge < 1 || userAge > 120) 
       {
           WriteRangeError();
           Continue;
       }

       inputIsValid = true;
   }
   return userAge;
}

private void WriteNumericalError()
{
    Console.ForegroundColor = ConsoleColor.Red;
    Console.Write("RANGE ");
    Console.ForegroundColor = ConsoleColor.White;
    Console.Write("error\n");
    Console.Write("Accepted range are numbers (eg. 123) ");
    Console.ForegroundColor = ConsoleColor.Red;
    Console.Write("between 1 and 120\n");
    Console.ForegroundColor = ConsoleColor.White;
}
private void WriteRangeError()
{
    Console.ForegroundColor = ConsoleColor.Magenta;
    Console.Write("TYPE ");
    Console.ForegroundColor = ConsoleColor.White;
    Console.Write("error\n");
    Console.Write("Accepted input types are ");
    Console.ForegroundColor = ConsoleColor.Magenta;
    Console.Write("numbers (eg. 123) ");
    Console.ForegroundColor = ConsoleColor.White;
    Console.Write("between 1 and 120\n");
}

In a switch statement the default is only hit if no break point is hit before.switch语句中,只有在之前没有命中break时才会命中default In your code, if your first case is met it won't return anything if (n < 1 || n > 120) evaluates to true .在您的代码中,如果满足您的第一种情况,如果(n < 1 || n > 120)评估为true ,它将不会返回任何内容。

Typically you use break to exit the switch statement and ensure only one case is triggered but in your case you want the case to trigger and the default trigger so you should remove the break .通常,您使用break退出 switch 语句并确保仅触发一种情况,但在您的情况下,您希望触发 case 和默认触发器,因此您应该删除break

However, I'd suggest that based on what you currently have a switch statement is less efficient and unnecessarily complicated for what you're doing.但是,我建议根据您目前拥有的 switch 语句对于您正在做的事情来说效率较低且不必要地复杂。

You might try something like this:你可以尝试这样的事情:

public static int CheckAge()
{
    int userAge;

    //while (true) is required to indicate infinite loop and clear the code paths error
    while (true)
    {
        Console.Write("Enter your age: ");
        string stringAge = Console.ReadLine();

        if (int.TryParse(stringAge, out userAge))
        {
            if (userAge < 1 || userAge > 120)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("RANGE ");
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write("error\n");
                Console.Write("Accepted range are numbers (eg. 123) ");
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("between 1 and 120\n");
                Console.ForegroundColor = ConsoleColor.White;
            }
            else
            {
                return userAge;
            }
        }
        else
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.Write("TYPE ");
            Console.ForegroundColor = ConsoleColor.White;
            Console.Write("error\n");
            Console.Write("Accepted input types are ");
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.Write("numbers (eg. 123) ");
            Console.ForegroundColor = ConsoleColor.White;
            Console.Write("between 1 and 120\n");
        }
    }
}

When I ran your code, the compiler yelled at me saying "not all code paths return a value".当我运行您的代码时,编译器对我大喊“并非所有代码路径都返回值”。 I made the two changes commented below and it worked fine for me at that point.我做了下面评论的两个更改,当时对我来说效果很好。

public static int CheckAge()
{
    int userAge = 0; //I added =0 to appease the compiler warnings
    bool inValidInput = true;
    while (inValidInput)
    {
         //your existing code   
    }
    return userAge;  //added this to appease the compiler
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM