c# – 当没有指定的情况可以处理时,在switch语句中抛出异常

我一直在写C#的最近8年,已经成为相当防守的OOP程序员。使用静态类型语言,你做的事情就像在方法中验证参数,抛出异常,你不会在动态和更自由的语言。我认为自己是一个C#的专家,并寻找其他精通C#开发人员的反馈最佳做法。

假设我们有一个函数可以在MVC应用程序的系统中更改用户的密码:

public JsonResult ChangePassword
    (string username, string currentPassword, string newPassword)
{
    switch (this.membershipService.ValidateLogin(username, currentPassword))
    {
        case UserValidationResult.BasUsername:
        case UserValidationResult.BadPassword:
            // abort: return JsonResult with localized error message        
            // for invalid username/pass combo.
        case UserValidationResult.TrialExpired
            // abort: return JsonResult with localized error message
            // that user cannot login because their trial period has expired
        case UserValidationResult.Success:
            break;
    }

    // NOW change password now that user is validated
}

membershipService.ValidateLogin()返回一个UserValidationResult枚举,定义为:

enum UserValidationResult
{
    BadUsername,
    BadPassword,
    TrialExpired,
    Success
}

作为一个防御性程序员,我将更改上述ChangePassword()方法,如果有一个无法识别的UserValidationResult值从ValidateLogin()返回一个异常:

public JsonResult ChangePassword
    (string username, string currentPassword, string newPassword)
{
    switch (this.membershipService.ValidateLogin(username, currentPassword))
    {
        case UserValidationResult.BasUsername:
        case UserValidationResult.BadPassword:
            // abort: return JsonResult with localized error message        
            // for invalid username/pass combo.
        case UserValidationResult.TrialExpired
            // abort: return JsonResult with localized error message
            // that user cannot login because their trial period has expired
        case UserValidationResult.Success:
            break;
        default:
            throw new NotImplementedException
                ("Unrecognized UserValidationResult value.");
            // or NotSupportedException()
            break;
    }

    // Change password now that user is validated
}

我总是认为一个模式像最后一个片段上面的最佳实践。例如,如果一个开发者在用户尝试登录时遇到要求,如果出于这个或那个业务原因,他们想要先联系该业务?所以UserValidationResult的定义更新为:

enum UserValidationResult
{
    BadUsername,
    BadPassword,
    TrialExpired,
    ContactUs,
    Success
}

开发人员更改ValidateLogin()方法的主体以在适用时返回新的枚举值(UserValidationResult.ContactUs),但忘记更新ChangePassword()。没有交换机中的例外,用户仍然可以更改他们的密码,当他们的登录尝试不应该甚至首先被验证!

它只是我,或者是这个默认值:throw new Exception()一个好主意?我几年前看到它,并总是(在groking后)认为它是一个最佳实践。

最佳答案
我总是在这种情况下抛出异常。考虑使用InvalidEnumArgumentException,这在这种情况下提供更丰富的信息。

转载注明原文:c# – 当没有指定的情况可以处理时,在switch语句中抛出异常 - 代码日志