C#: Python中try/catch/else块的等价物

9 投票
10 回答
4488 浏览
提问于 2025-04-15 19:59

在Python中,有一段很有用的异常处理代码:

try:
    # Code that could raise an exception
except Exception:
    # Exception handling
else:
    # Code to execute if the try block DID NOT fail

我觉得把可能会出错的代码和正常代码分开写是很有用的。在Python中,可以像上面那样做到这一点,但我在C#中找不到类似的东西。

假设没有这样的功能,通常的做法是把正常代码放在try块里,还是放在catch块之后呢?

我问这个的原因是因为我有以下代码:

if (!IsReadOnly)
{
    T newobj;
    try
    {
        newobj = DataPortal.Update<T>(this);

        List<string> keys = new List<string>(BasicProperties.Keys);
        foreach (string key in keys)
        {
            BasicProperties[key] = newobj.BasicProperties[key];
        }
    }
    catch (DataPortalException)
    {
        // TODO: Implement DataPortal.Update<T>() recovery mechanism
    }
}

这段代码需要正常代码放在try块里,因为如果发生了异常并被处理了,newobj就会没有被赋值,但把这么多和DataPortalException无关的代码放在try块里感觉很不自然。我该怎么办呢?

谢谢

10 个回答

3

C# 语言没有这样的概念,所以你只有三种选择:

  • 把 else 的代码放在 try 里面。
  • 把 else 的代码放在 try catch 块外面,使用一个局部变量来表示成功或失败,然后在 else 代码周围加一个 if 块。
  • 把 else 的代码放在 finally 块里,使用一个局部变量来表示成功或失败,然后在 else 代码周围加一个 if 块。
8

一种粗暴的解决办法是:创建一个叫做 Else 的类,让它继承自 Exception(异常),然后在 try 块的最后抛出这个类的一个实例。接着用 catch (Else) {...} 来处理其他的事情。

我觉得这样做很不干净。

9

我更希望看到其余的代码放在try/catch之外,这样就能清楚地知道你想捕获的异常是从哪里来的,也能避免意外捕获到你并不想处理的异常。

我觉得,Python中的try/catch/else最接近的做法是使用一个本地的布尔变量来记住是否抛出了异常。

bool success;

try
{
    foo();
    success = true;
}
catch (MyException)
{
    recover();
    success = false;
}

if (success)
{
    bar();
}

但是如果你这样做的话,我想问问你,为什么不完全处理这个异常,这样就能继续像成功一样运行,或者干脆中止,返回一个错误代码,甚至让异常继续传递给调用者。

撰写回答