Closed. This question is opinion-based。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
                        
                        3年前关闭。
                                                                                            
                
        
这个问题是关于约定和解释MSDN的,所以我认为它主要不是基于意见的。

我想知道ArgumentException:我有一个生成器类,该类用于构建过滤器对象,该对象将在从邮箱中检索一组电子邮件消息时应用。该构建器具有多种设置过滤器选项的方法。例如,我有两种方法来设置过滤器的“发送日期”范围-在XX之前发送和/或在XX之后发送。我想为每个子项添加一个保护子句,例如,如果提供的“之前”日期晚于提供的“之后”日期,则将引发异常。我可以使用一种常见的验证方法来做到这一点:

/// <summary>
/// This class provides methods for validating dates in various ways.
/// </summary>
internal static class DateValidation
{
    /// <summary>
    /// Validate the provided "start" and "end" date/time values.
    /// If they do not represent a valid range, throw an exception.
    /// </summary>
    /// <param name="start">The date/time that represents the start of the range.</param>
    /// <param name="end">The date/time that represents the end of the range.</param>
    internal static void ValidateDateTimeRange(DateTime? start, DateTime? end)
    {
        if (start.HasValue && end.HasValue)
        {
            if (start.Value > end.Value)
                throw new Exception(
                string.Format(@"The start date/time ""{0}"" " +
                @"occurs after the end date/time ""{1}"".",
                start.ToString(), end.ToString()));
        }
    }
}


这是两个构建器方法:

/// <summary>
/// Set a value which represents a date/time after which
/// messages must have been sent to be part of filtered output.
/// </summary>
/// <param name="afterDateTime">The date/time after which
/// messages must have been sent to be part of filtered output.</param>
public void SetSentAfterDateTime(DateTime afterDateTime)
{
    DateValidation.ValidateDateTimeRange(afterDateTime, _sentBeforeDateTime);
    _sentAfterDateTime = afterDateTime;
}

/// <summary>
/// Set a value which represents a date/time before which
/// messages must have been sent to be part of filtered output.
/// </summary>
/// <param name="beforeDateTime">The date/time before which
/// messages must have been sent to be part of filtered output.</param>
public void SetSentBeforeDateTime(DateTime beforeDateTime)
{
    DateValidation.ValidateDateTimeRange(_sentAfterDateTime, beforeDateTime);
    _sentBeforeDateTime = beforeDateTime;
}


根据MSDN


  最常见的是,通用语言会引发ArgumentException
  运行时或其他类库,并指示开发人员错误。


我知道“最常见”一词为其他用法(如我的用法)留出了可能性,但我喜欢遵守惯例。我正在构建一个公共API,因此该异常将被记录下来,并且会超出公共接口的范围。此外,它不会“表明开发人员错误”。可以想象,它可以指示用户错误(使用异常处理用户输入验证问题是一种常见的约定)。但是,基于MSDN的描述,我感到这不是它想要的。


  ...派生类[ArgumentNullException和
  应该使用ArgumentOutOfRangeException]代替
  ArgumentException,除非其中两个都不是
  类是可以接受的。例如,应该通过以下方式抛出异常:
  
  ...
  
  ArgumentOutOfRangeException,当参数的值在外部时
  可接受值的范围;例如,当值“ 46”为
  在创建DateTime期间作为月参数传递。


我的论点可能不在可接受的值范围内,但该条件是根据其他日期/时间值动态确定的。没有“超出范围”的静态值范围。

那么ArgumentException通常用于这种情况吗?

最佳答案

摘自Krzysztof Cwalina的How to Design Exception Hierarchies


  使用错误是可以通过更改调用例程的代码来避免的。


我们同意这是使用错误。

埃里克·利珀特(Eric Lippert)称他们为Boneheaded exceptions


  骨头异常是您自己的糟糕错误,您可以阻止它们,因此它们是代码中的错误。你不应该抓住他们;这样做是在代码中隐藏一个错误。


开发人员不应catch这些类型的错误,而应更改调用代码,以确保从头开始就不会发生异常。这就是为什么确切的异常类型没有太大关系的原因。

正如Cwalina解释的那样:


  使用错误需要传达给调用例程的开发人员。异常类型不是向人类传达错误的最佳方法。消息字符串是一种更好的方法。因此,对于因使用错误而引发的异常,我将集中精力设计一个真正好的(说明性)异常消息,并使用现有的.NET Framework异常类型之一:ArgumentNullException,ArgumentException,InvalidOperationException,NotSupportedException等换句话说,不要为使用错误创建新的异常类型,因为异常的类型与使用错误无关。 .NET Framework已经具有足够的类型(实际上太多,恕我直言)来表示我能想到的每个使用错误。


(强调我的)

您使用的是ArgumentException还是InvalidOperationException都没有关系。选择一个,但请确保其具有清晰的Message

关于c# - 我应该抛出ArgumentException吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40385277/

10-12 23:58