考虑以下类和方法:
public class MyDto
{
public MyDtoChild Child {get; set;}
}
和
public void ProcessDto(MyDto myDto)
{
if(myDto == null) throw new ArgumentNullException("myDto");
this.CheckSomething(myDto.Child.ChildProperty);
}
如果使用MyDto
调用并将Child
留给它自己的设备,则会抛出NullReferenceException
,这在更复杂的方法中很难诊断。
通常,如果ArgumentNullException
为null,则在方法的开头抛出myDto
但是如果myDto.Children
为空,则抛出的适当例外是什么? ArgumentNullException
?一个NullReferenceException
?自定义异常?
答案 0 :(得分:5)
如前面的答案所述,它不应该是ArgumentNullException
,因为参数myDTO
不是NULL。
对我来说,抛出ArgumentException
更有意义,因为传递给方法的参数不符合要求(您希望Children不为null)。此外,您的情况符合ArgumentException的描述:
调用方法时至少抛出一个方法时抛出ArgumentException 传递的参数不符合参数规范 被叫方法。
答案 1 :(得分:4)
绝对不是ArgumentNullException
。如果您可以访问myDto的属性Children,这意味着myDto是参数,不为空。因此,没有ArgumentNullException作为myDto本身 not null 。
正如您所建议的那样,您可以抛出NullReferenceException
并添加自己的消息,以便了解其来源并妥善解释。这完全是逻辑,因为您要使用的属性的引用是 null 。
正如@Silvermind所提到的,不应该使用NullReferenceException。相反,您还有其他选项,例如ArgumentException
或InvalidOperationException
。另一种选择是创建自己的异常类型,该类型派生自Exception
类。
示例:
public class ChildNullException: Exception
{
public ChildNullException() { }
public ChildNullException(string message)
: base(message)
{
}
public ChildNullException(string message, Exception inner)
: base(message, inner)
{
}
}
答案 2 :(得分:4)
如果参数为非null但以某种方式无效,则应抛出ArgumentException
:
if(myDto == null) throw new ArgumentNullException("myDto");
if(myDto.Child == null) throw new ArgumentException("Property Child must not be null.", "myDto");
答案 3 :(得分:3)
你的论证的孩子不是你的论据,所以ArgumentNullException
在这里不合适。我认为最好的方法是向NullReferenceException
发送一条解释信息。
答案 4 :(得分:2)
根据您的解释,我发现这是一个程序逻辑错误,而不是数据问题。您可以在调用此方法之前加载子实体,并且一切正常,或者您不加载子级,并且无法执行此逻辑。所以,在这里抛出一些自定义异常是没有意义的,因为在你第一次修复问题之后,问题不会再发生了。只看堆栈跟踪异常,修复程序逻辑并忘记这种情况。为此使用全局异常处理程序。