.net c#返回值方法中的异常处理

Exception handling in return value methods
2020-10-17
  •  译文(汉语)
  •  原文(英语)

我正在研究一种应遵循以下逻辑的方法:

  • 提示用户在控制台中输入数字
  • 尝试将输入转换为整数
    • 如果成功,则返回整数
    • 如果失败,则将错误消息写入控制台并重新启动方法

这是我所拥有的:

static int GetPlayers()
{
    int players = 0;

    Console.Write("How many people are playing?");

    try
    {
        players = Convert.ToInt16(Console.ReadLine());
    }
    catch (Exception e)
    {
        Console.Write(e.Message + "\n" +
            "----------");
        GetPlayers();
    }

    return players;
}

问题很简单,"并非所有代码路径都返回值".我可以让它做我想做的事,但是它将有几个丑陋的条件语句,它们反映了我有多少业余爱好者.我正在寻找一种优雅的专业级解决方案,以帮助我学习将来如何正确处理此类逻辑序列.

先感谢您!

速聊1:
尝试 int.TryParse(Console.ReadLine(),out players)?Console.Write(players):"something cool"
速聊2:
这段代码不会为我产生该错误.问题一定在其他地方.就是说,通常使用循环比使用递归重复某些内容更好.
解决过程1

您必须对return方法进行第二次调用的结果.如果仅调用该方法而不返回值,则结果为0(如果发生错误).

您也可以这样做players = GetPlayers(),我认为它更优雅,因为该方法只有一种出路.

static int GetPlayers()
{
    int players = 0;

    Console.Write("How many people are playing?");

    try
    {
        players = Convert.ToInt16(Console.ReadLine());
    }
    catch (Exception e)
    {
        Console.Write(e.Message + "\n" +
            "----------");
       return GetPlayers(); // return the result
    }

    return players;
}

用法如下所示:

static void Main(string[] args)
{
    var players = GetPlayers();
    Console.WriteLine("Players count: " + players);
    Console.ReadLine();
}

输出如下:

How many people are playing?s 
Input string was not in a correct format.
----------How many people are playing?9
Players count: 9
速聊1:
再次测试了100%它的工作原理.您能解释一下"不起作用"的意思吗?
速聊2:
奇怪.我第一次尝试通过将返回值放在GetPlayers()前面来尝试它;它不承认它是返回路径,给了我同样的错误信息.我第二次复制了您的代码,但没有错误地将其粘贴了.我一定在某个地方犯了一个错误.抱歉! 并感谢您的快速回复.
解决过程2

您可以使用while循环,只有正确设置播放器后才返回.

static int GetPlayers()
{
    int? players;

    Console.Write("How many people are playing?");

    while (players == null)
    {
      try
      {
          players = Convert.ToInt16(Console.ReadLine());
      }
      catch (Exception e)
      {
          Console.Write(e.Message + "\n" + "----------");
      }
    }

    return players.Value;
}
速聊1:
/ facepalm我觉得这将是非常简单的事情.现在我遇到"无法隐式转换类型'int?' 到'int'.存在显式转换(您是否缺少类型转换?)".我知道我可以通过使用初始分配0并将其用作while循环中的条件来避免它,但是我不知道如何解决它.
速聊2:
将返回玩家更改为返回玩家.
解决过程3

特殊的代码路径不会返回值,编译器会注意到这一点.这是一个错误,在捕获异常时永远不会罕见.通常,您不假设用户键入错误的内容有什么例外,所以您通常处于领先地位.此外,这不是您唯一需要检查的内容,您也不会对-1或3000名玩家感到满意.

只要创建一个无尽的循环,当您输入正确的条目时就可以逃避.像这样:

    static int GetPlayers(int max = 10) {
        for (;;) {
            Console.Write("Number of players: ");
            int players;
            if (int.TryParse(Console.ReadLine(), out players)) {
                if (players > 0 && players <= max) return players;
            }
            Console.WriteLine("  Oops, please type a number between 1 and " + max.ToString());
        }
    }

一些程序员发现了for (;;)光栅,我不是其中之一.while (true)如果讨厌,可以使用.

I'm working on a method that should follow this logic:

  • Prompt the user to enter a number into the console
  • Try to convert the input to an integer
    • If successful, return the integer
    • If unsuccessful, write the error message to console and restart the method

Here's what I have:

static int GetPlayers()
{
    int players = 0;

    Console.Write("How many people are playing?");

    try
    {
        players = Convert.ToInt16(Console.ReadLine());
    }
    catch (Exception e)
    {
        Console.Write(e.Message + "\n" +
            "----------");
        GetPlayers();
    }

    return players;
}

The problem is simple, "not all code paths return a value." I can get it to do what I want, but it's going to have a couple ugly conditional statements that reflect how much of an amateur I am. I'm looking for an elegant, professional-grade solution to help me learn how to properly handle this type of logical sequence in the future.

Thank you in advance!

Talk1:
try int.TryParse(Console.ReadLine(),out players)?Console.Write(players):"something cool"
Talk2:
This code does not produce that error for me. The problem must be somewhere else. That said, it is usually better to use a loop than recursion to repeat something.
Solutions1

You have to return the result of the second call of the method. If you just call the method without returning the value, the result will be 0 (if an error has been made).

You also could do players = GetPlayers() which I think it's more elegant because the method will have only one way out.

static int GetPlayers()
{
    int players = 0;

    Console.Write("How many people are playing?");

    try
    {
        players = Convert.ToInt16(Console.ReadLine());
    }
    catch (Exception e)
    {
        Console.Write(e.Message + "\n" +
            "----------");
       return GetPlayers(); // return the result
    }

    return players;
}

The usage will look something like this:

static void Main(string[] args)
{
    var players = GetPlayers();
    Console.WriteLine("Players count: " + players);
    Console.ReadLine();
}

The output is like following:

How many people are playing?s 
Input string was not in a correct format.
----------How many people are playing?9
Players count: 9
Talk1:
tested again 100% that it works. Can you explain what you mean by "doesn't work"?
Talk2:
Strange. The first time I tried it by simply putting the return in front of the GetPlayers(); and it didn't acknowledge it as a return path, giving me the same error message. I copied your code the second time and pasted it in without an errors though. I must have made a mistake somewhere. Sorry! And thanks for the quick response.
Solutions2

You could use a while loop and only return once players is set correctly.

static int GetPlayers()
{
    int? players;

    Console.Write("How many people are playing?");

    while (players == null)
    {
      try
      {
          players = Convert.ToInt16(Console.ReadLine());
      }
      catch (Exception e)
      {
          Console.Write(e.Message + "\n" + "----------");
      }
    }

    return players.Value;
}
Talk1:
/facepalm I had a feeling it was going to be something very simple. Now I'm running into "Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)". I know I could avoid it by using an initial assignment of 0 and using that as the condition in the while loop, but I don't know how to fix it.
Talk2:
Change return players to return players.Value
Solutions3

The exceptional code path doesn't return a value, the compiler notices that. It is a bug, never uncommon when you catch exceptions. You are usually ahead by not assuming that there's anything exceptional about the user typing something wrong. Besides, it isn't the only thing that you ought to check, you are not going to be happy about -1 or 3000 players either.

Just create an endless loop that you escape from when you got a correct entry. Like this:

    static int GetPlayers(int max = 10) {
        for (;;) {
            Console.Write("Number of players: ");
            int players;
            if (int.TryParse(Console.ReadLine(), out players)) {
                if (players > 0 && players <= max) return players;
            }
            Console.WriteLine("  Oops, please type a number between 1 and " + max.ToString());
        }
    }

Some programmers find for (;;) grating, I'm not one of them. You can use while (true) if you hate it.

转载于:https://stackoverflow.com/questions/30816178/exception-handling-in-return-value-methods

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入