哪个异常被调用了?

7

如果我有一个例程,在两个地方可能会抛出ArgumentException的情况下,类似于...

if (Var1 == null)
{
    throw new ArgumentException ("Var1 is null, this cannot be!");
}

if (Val2  == null)
{
    throw new ArgumentException ("Var2 is null, this cannot be either!");
}

在我的调用过程中,如何最好地确定抛出了哪个异常?

或者

我这样做是不是有问题?

10个回答

12

针对这种特定情况,您应该使用ArgumentNullException,并正确填充它的ParamName属性,以便知道哪个参数为空。

ArgumentException类也支持相同的属性,但您应该使用可用的最具体的异常类型。

在使用这些类型的异常时,还要注意在使用同时接受消息和参数名称的构造函数时。每种异常类型之间的顺序会被交换:

throw new ArgumentException("message", "paramName");

throw new ArgumentNullException("paramName", "message");

11
在ArgumentException构造函数的第二个参数中传递变量名称(如Val1,Val2等)。这将成为ArgumentException.ParamName属性。

4

您的调用函数不应该关心哪一行引起了异常。无论哪种情况,都会抛出一个ArgumentException,并且两种情况都应以相同的方式处理。


此外,在调用该方法之前,这也可以很容易地进行检查。 - Skurmedel
但是如果我想根据抛出的两个异常之一向用户显示特定的消息呢? - Rob
你可以使用异常本身的文本,或者抛出ArgumentNullException - Justin Ethier

3
使用构造函数ArgumentException(string, string)来定义哪个参数为空。
if (Var1 == null) {
  throw new ArgumentException ("Var1 is null, this cannot be!","Var1");
}

if (Val2  == null){
  throw new ArgumentException ("Var2 is null, this cannot be either!","Var2");
}

3
您应该问自己的更大问题是为什么?如果您试图从中推导出某种逻辑,那么异常通常不是好的方法。相反,您应该有一个返回类型(或out/ref参数),它将被设置为某种标志/值,您可以从调用代码中检测到以确定错误并驱动您的逻辑。如果您坚持使用异常,则在这种情况下,ArgumentNullException有一个构造函数,它需要参数的名称和异常消息。您可以抛出异常,然后当您捕获异常时,访问ParamName属性以确定引发异常的参数的名称。

3
您没有提供足够的信息来回答您的问题。显而易见的答案是查看异常的消息,但我猜这不是您要找的。
如果真的很重要,您需要能够以编程方式将它们区分开来,那么使用另一个异常,或者至少使用当前异常构造函数的 paramName 属性。这将为您提供更相关的信息。
然而,使用自己的异常类型是确保您捕获特定情况下异常的唯一方法。因为 ArgumentException 是框架的一部分,所以可能会有其他您调用的东西抛出它,这会导致您进入相同的 catch 块。如果您创建自己的异常类型(为两种情况之一或为两种情况都创建一个),这将为您提供处理特定错误的方法。当然,根据您的示例,似乎简单地在调用函数之前检查 Val1 或 Val2 是否为空会更简单。

2

对于特定的ArgumentException,您需要一个参数来确定出现问题的参数:

throw new ArgumentException("Var1 is null, this cannot be!", "Var1");

从更一般的意义上讲,通常您会使用不同(可能是自定义的)异常类型,然后调用代码可以有不同的catch块。

public class MyCustomException1 : ApplicationException {}
public class MyCustomException2 : ApplicationException {}


try
{
 DoSomething();
}
catch(MyCustomException1 mce1)
{
}
catch(MyCustomException2 mce2)
{
}
catch(Exception ex)
{
}

在这种情况下,ArgumentException的第二个参数应该是一个字符串,即有问题的参数的名称。 - Polyfun

0
try
        {
            //code here
        }
        catch (ArgumentException ae)
        {
            Console.WriteLine(ae.ToString());
        }

在你的控制台中输出将显示你所输入的信息。


0

如果这是一个测试用例,您想确保正确的异常消息被显示,我知道 NUnit 有一个 ExpectedMessage 关键字到 ExpectedException 属性。否则,ArgumentNullException 就是 ArgumentNullException,您的应用程序应该将它们全部视为相同。如果您想要更多细节,请创建自己的异常类并使用它们。

因此,您可以测试以下内容:

[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var1 is null, this cannot be!"]
public void TestCaseOne {
    ...
}

[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var2 is null, this cannot be either!"]
public void TestCaseTwo {
    ...
}

0

在抛出ArgumentExceptions时,您可以始终包含引起异常的参数名称(它是另一个构造函数)。当然,我假设您真的想知道哪个参数为空,在这种情况下,您应该使用ArgumentNullException


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接