当没有指定的案例可以处理时,在switch语句中抛出异常

Can*_*ain 59 c# exception switch-statement

Let's say we have a function that changes a password for a user in a system in an MVC app.:

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
}
Run Code Online (Sandbox Code Playgroud)

membershipService.ValidateLogin() returns a UserValidationResult enum that is defined as:

enum UserValidationResult
{
    BadUsername,
    BadPassword,
    TrialExpired,
    Success
}
Run Code Online (Sandbox Code Playgroud)

Being a defensive programmer, I would change the above ChangePassword() method to throw an exception if there's an unrecognized UserValidationResult value back from 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
}
Run Code Online (Sandbox Code Playgroud)

I always considered a pattern like the last snippet above a best practice. For example, what if one developer gets a requirement that now when users try to login, if for this-or-that business reason, they're suppose to contact the business first? So UserValidationResult's definition is updated to be:

enum UserValidationResult
{
    BadUsername,
    BadPassword,
    TrialExpired,
    ContactUs,
    Success
}
Run Code Online (Sandbox Code Playgroud)

开发人员更改ValidateLogin()方法的主体以UserValidationResult.ContactUs在适用时返回新的枚举值(),但忘记更新ChangePassword().如果没有交换机中的例外,用户仍然可以在首次验证登录尝试时更改密码!

这只是我,还是这个default: throw new Exception()好主意?几年前我就看到了它,并且总是(在研究之后)认为这是一种最佳实践.

Mat*_*eer 84

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

  • 我认为如果它显示了一个带有用法的代码片段,答案会更好.类似于`default:throw new System.ComponentModel.InvalidEnumArgumentException(nameof(userType),(int)userType,userType.GetType());` (5认同)
  • 仅当受到enum是参数时,这在语义上是正确的.情况并非总是如此:http://stackoverflow.com/questions/13645149/what-is-the-correct-exception-to-throw-for-unhandled-enum-values (4认同)
  • 哦,非常好,以前没见过这个Exception衍生物.谢谢 :) (2认同)