C#校验用户信息:抛出异常还是返回字符串?
如何在C#中优雅处理校验失败的原因反馈?
我写了一个校验用户信息的C#函数,代码如下:
//校验用户信息是否合法。 private bool checkUserDatails(String nickname, String groupId) { //校验昵称 if ((nickname == null || nickname.Trim().Equals(""))) { return false; } //校验groupId if (groupId == null) return false; //转换为int类型 int id; try { id = int.Parse(groupId); } catch (Exception) { return false; } //校验id范围 if (id < 0 | id > 100) return false; return true; }
这个函数能正常运行,但调用方根本不知道返回false的时候具体是哪里出了问题——是昵称空了?还是groupId格式不对?还是ID超出范围了?我考虑过自定义IncorrectUsernameException这类异常抛出,也想过把返回值改成字符串直接返回失败提示,但不确定哪种是C#里的正确处理方式,求指导!
嘿,这个场景太常见了!在C#里处理这种“需要返回校验失败原因”的需求,其实有几种成熟的方案,咱们一个个说:
方案1:自定义异常类(适合校验失败属于异常场景的情况)
如果你的业务逻辑里,“用户信息不合法”是一种不应该出现的异常情况(比如正常流程下调用方应该保证数据合法,只有异常情况才会校验失败),那自定义异常是很合适的选择。
首先定义几个针对性的异常类(或者一个带错误码/错误信息的基类):
public class InvalidUserDataException : Exception { public InvalidUserDataException(string message) : base(message) { } } // 也可以细分更具体的异常,比如: public class EmptyNicknameException : InvalidUserDataException { public EmptyNicknameException() : base("昵称不能为空或仅包含空白字符") { } } public class InvalidGroupIdFormatException : InvalidUserDataException { public InvalidGroupIdFormatException() : base("GroupId必须是有效的整数") { } } public class GroupIdOutOfRangeException : InvalidUserDataException { public GroupIdOutOfRangeException() : base("GroupId必须在0到100之间") { } }
然后修改你的校验函数,抛出对应的异常:
private void ValidateUserData(string nickname, string groupId) { // 校验昵称 if (string.IsNullOrWhiteSpace(nickname)) { throw new EmptyNicknameException(); } // 校验groupId非空 if (groupId == null) { throw new InvalidGroupIdFormatException(); } // 转换并校验范围(用TryParse替代try-catch更优雅) if (!int.TryParse(groupId, out int id)) { throw new InvalidGroupIdFormatException(); } if (id < 0 || id > 100) // 这里注意你原来的|是按位或,应该用||逻辑或哦 { throw new GroupIdOutOfRangeException(); } }
调用方就可以通过try-catch捕获异常,根据异常类型或者消息来处理:
try { ValidateUserData(" ", "abc"); } catch (EmptyNicknameException ex) { Console.WriteLine(ex.Message); // 输出昵称相关错误 } catch (InvalidGroupIdFormatException ex) { Console.WriteLine(ex.Message); // 输出格式错误 }
方案2:返回自定义结果对象(适合校验失败属于预期场景的情况)
如果用户信息不合法是业务流程里的常见情况(比如用户输入错误后需要提示),那返回一个包含“是否成功”和“错误信息”的结果对象会更友好,避免用异常来控制流程。
先定义一个结果类:
public class ValidationResult { public bool IsValid { get; set; } public string ErrorMessage { get; set; } // 静态方法方便创建实例 public static ValidationResult Success() => new ValidationResult { IsValid = true }; public static ValidationResult Fail(string message) => new ValidationResult { IsValid = false, ErrorMessage = message }; }
然后修改校验函数返回这个对象:
private ValidationResult CheckUserDatails(string nickname, string groupId) { if (string.IsNullOrWhiteSpace(nickname)) { return ValidationResult.Fail("昵称不能为空或仅包含空白字符"); } if (groupId == null) { return ValidationResult.Fail("GroupId不能为空"); } if (!int.TryParse(groupId, out int id)) { return ValidationResult.Fail("GroupId必须是有效的整数"); } if (id < 0 || id > 100) { return ValidationResult.Fail("GroupId必须在0到100之间"); } return ValidationResult.Success(); }
调用方使用起来也很直观:
var result = CheckUserDatails("小明", "101"); if (!result.IsValid) { Console.WriteLine($"校验失败:{result.ErrorMessage}"); } else { // 处理合法数据 }
方案3:使用输出参数传递错误信息(轻量场景)
如果不想定义额外的类或异常,也可以用out参数来传递错误信息:
private bool CheckUserDatails(string nickname, string groupId, out string errorMessage) { errorMessage = string.Empty; if (string.IsNullOrWhiteSpace(nickname)) { errorMessage = "昵称不能为空或仅包含空白字符"; return false; } if (groupId == null) { errorMessage = "GroupId不能为空"; return false; } if (!int.TryParse(groupId, out int id)) { errorMessage = "GroupId必须是有效的整数"; return false; } if (id < 0 || id > 100) { errorMessage = "GroupId必须在0到100之间"; return false; } return true; }
调用方式:
if (!CheckUserDatails("", "99", out string error)) { Console.WriteLine(error); }
怎么选?
- 如果校验失败是异常情况(比如内部调用,调用方应该保证数据合法):用自定义异常。
- 如果校验失败是预期的业务场景(比如用户输入校验):用自定义结果对象。
- 如果是简单的小场景,不想加额外类型:用输出参数。
另外提个小建议:你原来代码里的id < 0 | id > 100用了按位或|,应该改成逻辑或||,虽然这里结果一样,但逻辑或会短路求值,性能更好也更符合语义~
内容的提问来源于stack exchange,提问作者McLovin
相关产品推荐
相关产品推荐

