【问题标题】:C# checking what condition was met in if statement with multiple conditionsC#检查具有多个条件的if语句中满足什么条件
【发布时间】:2022-01-23 06:05:45
【问题描述】:

如果某些输入大于 7 或小于 0,我正在检查错误异常:

if (number1 > 7 || number1 < 0 || number2 > 7 || number2 < 0){
  throw new Exception("Invalid position <pos>");
}
catch (Exception e){
  Console.Write(e)
}

如何打印错误的编号?例如:number1 是 10 但 number2 是 3,我想打印“Invalid position ”

【问题讨论】:

  • throw new Exception($"Invalid position {number1}");?
  • 即使 number2 是错误的,它也会打印 number1。我想知道是否可以在不使用许多 if/elseif 语句的情况下检查 if 语句中满足什么条件。
  • 将一个if 拆分为两个:number1number2
  • 如果 number1 = 11 且 number2 = 12 会发生什么?如果有这种可能性,则不能使用 if 和 else if。

标签: c# exception conditional-statements


【解决方案1】:

我想知道是否可以在不使用许多 if/elseif 语句的情况下检查 if 语句中满足什么条件。

没有这样的方法,你必须拆分你的if。

if (number1 > 7 || number1 < 0 ){
  throw new Exception($"Invalid position <{number1}>");
}
elseif(number2 > 7 || number2 < 0) {
  throw new Exception($"Invalid position <{number2}>");
}
catch (Exception e){
  Console.Write(e)
}

【讨论】:

  • 如果 number1 = 11 且 number2 = 12 会发生什么?如果有这种可能性,则不能使用 if 和 else if。
  • 好吧,number1 抛出了一个异常——这正是我想的原始行为。您希望在这里看到两个值的聚合异常?
  • (参见与 Dmitry Bychenko 的讨论)
【解决方案2】:

最简单的做法是将这个 if 语句拆分为一个 func:

Func<int,int,int,bool> InRange= (number,low,high) =>
{
  if(number>high || number<low)
      return false;
  return true;
}

if(!InRange(number1,0,7))
  throw new Exception($"Invalid position <{number1}>");
if(!InRange(number2,0,7))
  throw new Exception($"Invalid position <{number2}>");

真的,虽然在像这些情况下,你的数字应该在某种列表中,所以它更像是:

foreach (var number in numbers)
  if(!InRange(number,0,7))
     throw new Exception($"Invalid position <{number}>");

此外,您不应使用硬编码数字,如 0 和 7。它们应该是输入或设置为常量

【讨论】:

  • 最简单的?真的吗? :)
  • 这似乎有点矫枉过正——不过对于一个新的贡献者来说,你有一个格式很好的帖子。欢迎。
  • 哈哈,是的,可能有点矫枉过正,但这是我想到的第一件事,我喜欢可重用性:P
【解决方案3】:

如果number1number2参数,您可以分别验证它们:

// if number1 and number2 are input parameters, we just validate them: 
if (number1 < 0 || number1 > 7)
  throw new ArgumentOutOfRangeException(nameof(number1), "Invalid position <pos>");
if (number2 < 0 || number2 > 7)
  throw new ArgumentOutOfRangeException(nameof(number2), "Invalid position <pos>");

如果number1number2 是某种设置,您可以利用相同的想法:

// If number1 and number2 are local variables, we have some inner problems
// in the routine. That's why I vote for - InvalidOperationException -
// something when wrong
if (number1 < 0 || number1 > 7)
  throw new InvalidOperationException(
    $"Invalid position <pos>, {nameof(number1)} = {number1} is out of [0..7] range.");
if (number2 < 0 || number2 > 7)
  throw new InvalidOperationException(
    $"Invalid position <pos>, {nameof(number2)} = {number2} is out of [0..7] range.");

请注意,投掷和捕捉(吞咽Exception 通常是一种不好的做法:您的代码应该只处理一个简单的情况number1number2 超出范围且不存在所有可能的异常情况

如果你想写一些警告并继续这样做,你可以完全摆脱异常抛出:

if (number1 > 7 || number1 < 0)
  Console.Write($"Invalid position <pos>: {nameof(number1)} is out of range");
else if (number2 > 7 || number2 < 0)
  Console.Write($"Invalid position <pos>: {nameof(number2)} is out of range");
else {
  // Both number1 and number2 are valid
}

【讨论】:

  • 不确定抛出多个异常是最好的主意。可能持有一个值以在一个异常中显示?
  • @OldDog:恕我直言,每个异常情况都应该彼此分开(因为它们是异常)。实际上,最多会抛出一个异常
  • 您对多个例外情况有所了解。但是如果异常是相似的并且是相同比较的一部分,我通常宁愿抛出一个并列出它们,而不是让用户必须看到 2 并关闭 2 个单独的窗口。但如 cmets 所述,如果 number1 = 11 和 number2 = 12 会有两个例外。
  • @OldDog:只会抛出一个异常:如果,比如说number1 = -123,那么将抛出异常,执行将被中断 它将在catch 块继续。从技术上讲,您可以将第二个 if 更改为 else if 但它不会改变流程
  • 好点。但是一旦执行被破坏,要么错过第二个,要么你必须在其他地方捕获它,这基本上意味着另一个例外?不用担心,答案被接受了。无论如何,我喜欢讨论。 :-)
【解决方案4】:

一个简单的解决方案,一个throw,与其他解决方案相反:

if (number1 > 7 || number1 < 0 || number2 > 7 || number2 < 0)
{
    var invalidNumbers = new List<string>();
    if(number1 > 7 || number1 < 0)
    {
        invalidNumbers.Add($"{number1}");
    }
    if (number2 > 7 || number2 < 0)
    {
        invalidNumbers.Add($"{number2}");
    }
    throw new Exception($"Invalid position {string.Join(", ",invalidNumbers)}");
}

如果number1number2number1number2 均错误,则会通过一个唯一异常通知您。

如果您的条件对于每个数字都相同,正如您可能暗示的那样:

如果某些输入大于 7 或小于 0

您可以使用 Linq 轻松概括并获得更优雅的代码:

var number1 = 8;
var number2 = -1;

var numbers = new List<int>
{
    number1,
    number2
    // Add as many numbers as you wish.
};

var wrongNumbers = numbers
    .Where(n => n > 7 || n < 0) // The condition to apply to all numbers.
    .ToList();
    
if(wrongNumbers.Any())
{
    var wrongNumbersAsString = string.Join(", ", wrongNumbers
        .Select(n => $"{n}"));

    throw new Exception($"wrong numbers: {wrongNumbersAsString}");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-20
    • 2012-12-17
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多