如果没有c#异常,如何处理和测试流控制

本文关键字:处理 测试 流控制 异常 何处理 如果没有 | 更新日期: 2023-09-27 18:14:57

对无效的方法进行处理和测试流程控制的正确方法是什么?我看到微软不推荐这种做法,那么正确的方法是什么?

这就是我如何处理不应该在我的方法中接受的参数:

    public void RentOutCar(ReservationInfo reservationInfo) 
    {
        try
        {
            if (string.IsNullOrEmpty(reservationInfo.ReservationNumber) || string.IsNullOrWhiteSpace(reservationInfo.ReservationNumber))
            {
                throw new ArgumentException("Reservation Number is null or empty.");
            }
            if (reservationInfo == null)
            {
                throw new ArgumentNullException("Null Reservation info.");
            }
            if (reservationInfo.Car == null)
            {
                throw new ArgumentNullException("No car registered to rent.");
            }
            if (reservationInfo.RentalDatetime == DateTime.MinValue || reservationInfo.RentalDatetime == DateTime.MaxValue)
            {
                throw new ArgumentException("Rental Date has an unreal value.");
            }
            if (reservationInfo.Car.Mileage <0)
            {
                throw new ArgumentOutOfRangeException("Mileage can't be less than 0.");
            }
            reserverationsRegister.ReservationsDone.Add(reservationInfo);
        }
        catch (Exception) 
        {
            throw;
        }
    }

如果没有c#异常,如何处理和测试流控制

这不是微软所说的不应该用异常来控制流的意思。

而使用异常处理程序捕获错误和其他事件认为中断程序执行是一种很好的做法,使用异常处理程序可以作为常规程序执行逻辑的一部分是昂贵的,应该避免。

换句话说,在try块中的代码可能抛出并表示合法的程序逻辑的情况下,您不应该抛出(并随后捕获)异常。

一个用异常控制流的人为示例如下:

int x = GetUserInput();
try
{
    MustAcceptPositiveInput(x);
}
catch (InputIsNonPositiveException)
{
    MustAcceptNonPositiveInput(x);
}

对应的"正确"代码可能如下所示:

int x = GetUserInput();
if (x > 0)
{
    MustAcceptPositiveInput(x);
}
else
{
    MustAcceptNonPositiveInput(x);
}

异常应该保留给不属于预期程序执行的异常情况。它的结果是更具可读性,更少的意外和更高的性能代码。

您在代码中所做的是好的(除了多余的try-catch和@Clay提到的错误的测试顺序),您正在验证异常值的输入,这些值是您的代码不打算处理的

如果输入无效则抛出异常。首先测试reservationInfo为null—否则您的其他测试将以意想不到的方式中断。另外,如果你要做的只是重新抛出它,那么在try/catch中包装测试是没有意义的。

这不是你在评论中所描述的"控制流"问题——在这里抛出异常是合适的。

你可以考虑在try/catch中只包装"工作代码",但前提是你可以从任何异常中恢复(或可能记录):

try
{
  reserverationsRegister.ReservationsDone.Add(reservationInfo);
}
catch( Exception ex )
{
  LogError( ex );
  throw;
}