通过调用函数中的异常保留当前函数

本文关键字:函数 保留 异常 调用 | 更新日期: 2023-09-27 17:59:46

假设我有这两个函数:

 private string otherString;
 private void Error(string message) {
     throw new Exception("Error: " + message);
 }
 private void Expected(string message) {
     Error("Expected " + message + " got " + otherString);
 }

现在我想写这样的代码:

 private int ReadInt() {
     int result = 0; 
     if(int.TryParse(otherString, out result)) {
         return result;
     }
     Expected("Int");
     //return 0; is need to compile but it will be never reached
 }

我知道编译器不能假设通过调用Expected来结束ReadInt函数。有没有其他方法可以做我想做的事情,而不需要在我想退出的每个地方都写throw语句并返回错误?

throw new Exception("Error: Expected Digit got " + otherString);

通过调用函数中的异常保留当前函数

您稍后可能会记录/捕获此异常,问题是,在当前设置中,您将不知道(直接)异常实际发生在哪里,从TargetSite中,您只能获得有关方法Error抛出异常的信息,而不能获得实际方法ReadInt的信息(尽管通过Stack Trace可以看到调用层次结构和ReadInt方法)

在您认为应该抛出异常的地方抛出异常,而不是从某些泛型方法抛出异常。此外,不是抛出基类异常,而是抛出特定的异常,如InvalidArgumentException

附带说明,如果您只关心解析相关的异常,那么不要使用TryParse方法组,让原始异常出现。

除了其他答案所说的(不要这样做,这不是一个好的做法)之外,你可以让错误方法返回一个假值来"欺骗"编译器:

private string otherString;
 private T Error<T>(string message) {
     throw new Exception("Error: " + message);
     return default(T);
 }
 private T Expected<T>(string message) {
     return Error<T>("Expected " + message + " got " + otherString);
 }
private int ReadInt() {
     int result = 0; 
     if(int.TryParse(otherString, out result)) {
         return result;
     }
     return Expected<int>("Int");
 }

另一种可能性(如注释中所建议的)是返回异常并将其抛出方法:

private string otherString;
 private Exception Error(string message) {
     return new Exception("Error: " + message);
 }
 private Expected(string message) {
     return Error("Expected " + message + " got " + otherString);
 }
private int ReadInt() {
     int result = 0; 
     if(int.TryParse(otherString, out result)) {
         return result;
     }
     throw Expected("Int");
 }

最后,但同样重要的是,您可以创建自己的异常并抛出该异常:

class ExpectedException : Exception
{
    public ExpectedException(string message)
       : base("Expected " + message + " got " + otherString)
    {}
}
private int ReadInt() {
     int result = 0; 
     if(int.TryParse(otherString, out result)) {
         return result;
     }
     throw new ExpectedException("Int");
 }