C# 是否可以向上抛出异常

C# 是否可以向上抛出异常,c#,exception-handling,windows-phone-7,C#,Exception Handling,Windows Phone 7,我正在研究这两种方法。一个保存,一个加载。显然,两者都需要某种错误处理,所以我实现了一些“全面处理”。现在搜索的重点是,接下来发生的事情与运行时错误发生的位置有关。因此,我想处理调用方中的错误,一级以上。这样我就可以在不同的情况下有不同的逻辑 例如。如果我在第一次运行时检查负载,但它失败了,我可以假定它们的内存可能已被清除。但是如果我在执行过程中尝试加载,我可以假设内存没有被清除(通过正确的方式),并且一定有什么事情发生了 public void SaveToStorage(Accoun

我正在研究这两种方法。一个保存,一个加载。显然,两者都需要某种错误处理,所以我实现了一些“全面处理”。现在搜索的重点是,接下来发生的事情与运行时错误发生的位置有关。因此,我想处理调用方中的错误,一级以上。这样我就可以在不同的情况下有不同的逻辑

例如。如果我在第一次运行时检查负载,但它失败了,我可以假定它们的内存可能已被清除。但是如果我在执行过程中尝试加载,我可以假设内存没有被清除(通过正确的方式),并且一定有什么事情发生了

    public void SaveToStorage(AccountCollection Collection)
    {
        try
        {
            var storage = IsolatedStorageSettings.ApplicationSettings;
            storage["defaultCollection"] = Collection;
            storage.Save();
        }
        catch (Exception ex)
        {
            // Do something meaningful here
        }
    }

    public AccountCollection LoadFromStorage()
    {
        try
        {
            AccountCollection collection;
            var storage = IsolatedStorageSettings.ApplicationSettings;
            storage.TryGetValue("defaultCollection", out collection);
            return collection;
        }
        catch (Exception ex)
        {
          // Do something meaningful here
        }

        return null;
    }
本质上,我是在问我是否可以将错误抛出给调用方,但仍然保留原始错误详细信息


编辑:约翰和安德鲁都给出了正确的答案。Andrew将得到绿色勾号,因为我想在原始类中执行一些其他通用清理。

如果您没有捕获异常,它将向上传播


这就是它的工作原理。不要到处放置try/catch块。只将它们放在实际处理异常的位置。

您可以在
catch
块中抛出原始异常(在当前代码中,可用作
ex
)。这实际上取决于您是否希望在这些函数中执行任何异常处理。如果您不想,请将try/catch块放在外部(将它们放在您希望处理异常的调用方中)。

对于所有关于不捕获的负面评论,他表示他希望在抛出异常的方法中进行一些展开,但也要在堆栈上继续,以便其他方法可以执行某些操作。他捕获异常并不是为了再次抛出异常,他希望执行一些操作,然后再次抛出异常

catch (Exception ex)
{
    // Do something
    throw;
}
编辑


由于某种原因,我把它看作是C++,所以删除了我关于复制异常的评论。然后让它冒泡到调用方法并在那里处理它。

这通常是通过
InnerException
属性将捕获的异常包装到新异常中来实现的。这样,您可以向调用者发送更有意义的详细信息和原始异常:

catch(Exception ex)
{
    // Do something...
    throw new MyOwnDataStorageException("message", ex);
}

或者,您可以什么也不做,异常将自动传播到具有完整调用堆栈的调用方

如果您想做的唯一一件事是重新播放异常,那么最好不要尝试/捕获,因为它会向上传播,但是如果您想做一些事情并重新播放,那么您需要:

catch(Exception ex)
{
    // Do your bit with ex

    throw;
}
通过使用just
throw
,可以保留有关异常的所有信息,包括堆栈跟踪


这个来自MSDN的示例听起来像是您可能正在寻找的

本例捕获原始异常,采取相应的操作(在本例中,向控制台写入一行),然后创建并抛出一个包含原始异常的新异常

class TestTryCatch
{
    static int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException e)  // CS0168
        {
            System.Console.WriteLine(e.Message);
            //set IndexOutOfRangeException to the new exception's InnerException
            throw new System.ArgumentOutOfRangeException("index parameter is out of range.", e);
        }
    }
}

throw
单独保留包括堆栈跟踪在内的所有信息。我非常肯定(但不是100%)throw ex会抛出异常,但会丢失堆栈信息。是的,这是正确的。使用
throw
可以保留堆栈信息。使用
throw-ex
throw-new-Exception
会丢失这些信息。@Jonathon修复了这个问题。理解他想要保留原来的堆栈而不是创建新的堆栈。干杯!那我就用扔吧@Jan:对于任何来自Java的人来说都有一个陷阱,
throw-ex
将保持异常对象不变,包括堆栈跟踪。感谢我不知道,一般来说,知道这一点很好,我相应地添加了rep。-1“throw-ex”只会让事情变得更糟。它使异常看起来像是从抛出的角度出现的。实际上,这里不一定有理由添加自定义异常,也不一定要进行任何包装。只要做“扔”,这取决于上下文。当然不一定。请澄清一下,你真的不想抓住它。对不起,是的,我的意思是,抓住你不能处理的东西是没有意义的。你最好让它冒泡起来,直到你能做点什么。