Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过调用函数中的异常离开当前函数_C#_Exception - Fatal编程技术网

C# 通过调用函数中的异常离开当前函数

C# 通过调用函数中的异常离开当前函数,c#,exception,C#,Exception,假设我有两个功能: private string otherString; private void Error(string message) { throw new Exception("Error: " + message); } private void Expected(string message) { Error("Expected " + message + " got " + otherString); } 现在我想编写如下代码: privat

假设我有两个功能:

 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
您将只获得有关抛出异常的方法
错误
的信息,而不是实际的方法
ReadInt
。(尽管通过堆栈跟踪,您可以看到调用层次结构和
ReadInt
方法)

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


作为旁注,如果您只关心解析相关异常,那么不要使用
TryParse
方法组,让原始异常冒泡

可能您稍后会记录/捕获此异常,问题是,使用当前设置,您将无法(直接)知道异常实际发生的位置,从
TargetSite
您将只获得有关方法
错误
引发异常的信息,而不是实际的方法
ReadInt
。(尽管通过堆栈跟踪,您可以看到调用层次结构和
ReadInt
方法)

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


作为旁注,如果您只关心解析相关异常,那么不要使用
TryParse
方法组,让原始异常冒泡

除了其他答案所说的以外(不要这样做,这不是一个好的做法),您可以通过让error方法返回一个假值来“愚弄”编译器:

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");
 }
最后,但并非最不重要的一点是,您可以创建自己的异常并抛出该异常:

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");
 }

除了其他答案所说的(不要这样做,这不是一个好的实践),您可以通过让error方法返回一个假值来“愚弄”编译器:

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");
 }
最后,但并非最不重要的一点是,您可以创建自己的异常并抛出该异常:

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");
 }


当你需要通知失败时写
throw
有什么不对?当你需要通知失败时写
throw
有什么不对?我认为这不是一个好的做法。抛出异常来表示错误情况比返回错误值要好得多,这是一种la C风格的编码。不是我的否决票,而是
如何返回默认值(T)语句。我打算向您建议类似的so+1,尽管这仍然让人感觉尴尬,而且通常不是一个好的做法。:)请看我的第一句话“不要那样做,这不是一个好的做法”。我只是想回答一个问题,就是他怎样才能避开这个问题。默认值(T)
永远不会执行,但至少他只需要在一个地方执行。这是一个解决问题的方法。@Kenneth,你也可以将
Excepted
Error
定义为一个返回
Exception
的方法,并像这样使用它们
抛出期望值(“Int”)
:)这样就不需要
默认值(t)
,我认为这不是一个好的做法。抛出异常来表示错误情况比返回错误值要好得多,这是一种la C风格的编码。不是我的否决票,而是
如何返回默认值(T)语句。我打算向您建议类似的so+1,尽管这仍然让人感觉尴尬,而且通常不是一个好的做法。:)请看我的第一句话“不要那样做,这不是一个好的做法”。我只是想回答一个问题,就是他怎样才能避开这个问题。默认值(T)
永远不会执行,但至少他只需要在一个地方执行。这是一个解决方案/黑客攻击一开始就不应该存在的问题。@Kenneth,您还可以将
Excepted
Error
定义为一个返回
Exception
的方法,并像这样使用
throw Expected(“Int”)
:)这样就不需要
默认值(t)
我将创建一个ExpectedException,它接受消息和其他字符串以获得相同的错误消息。这是一个Lexer,所以我不能对所有可能的标记使用解析异常。@Habib,stacktrace将包含有关
ReadInt
方法的信息,以及调用
预期的
的行号,因此发生的情况将非常清楚。但我同意在适当的地方抛出异常更为重要descriptive@LeonidVasilyev,你是对的,我修改了答案以澄清这一点。如果在异常发生的地方抛出异常,这是最简单的。堆栈跟踪中的第一个条目将始终位于错误发生的位置,将您带到代码中出现问题的地方。把它扔到其他地方意味着你必须记住它不是扔在那里的。更糟糕的是,如果其他人不得不修改代码&不知道引发异常的地方不是问题存在的地方!信息可能在堆栈跟踪中,但是如何让下一个家伙更容易呢?我将创建一个ExpectedException,它使用消息和其他字符串来获取相同的错误消息。这是用于词法分析器的,因此我不能对所有可能的标记使用解析异常。@Habib,stacktrace将包含有关
ReadInt
方法的信息,以及
exp