如何在C#中使用Java风格的throws关键字?

Lou*_*hys 82 c# java exception-handling throws

在Java中,throws关键字允许方法声明它不会自己处理异常,而是将其抛给调用方法.

C#中是否有类似的关键字/属性?

如果没有等效物,你怎么能达到相同(或相似)的效果呢?

ser*_*g10 96

op询问Java的throws子句C#等价物 - 而不是throw关键字.这用于Java中的方法签名,以指示可以抛出已检查的异常.

在C#中,没有直接等效的Java检查异常.C#没有等效的方法签名子句.

// Java - need to have throws clause if IOException not handled
public void readFile() throws java.io.IOException {
  ...not explicitly handling java.io.IOException...
}
Run Code Online (Sandbox Code Playgroud)

翻译成

// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile() 
{
  ...not explicitly handling System.IO.IOException...
}
Run Code Online (Sandbox Code Playgroud)


Ode*_*ded 67

在Java中,您必须处理异常或将方法标记为可以使用throws关键字抛出它的方法.

C#没有这个关键字或等效的关键字,如在C#中,如果你不处理异常,它会冒泡,直到被捕获或如果没有被捕获它将终止程序.

如果你想处理它然后重新抛出你可以做以下事情:

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}
Run Code Online (Sandbox Code Playgroud)

  • “it will bubble up”,这是否意味着这相当于Java中所有具有 throws 子句的方法? (4认同)
  • @AshishKamble - 呃.意见问题..NET中的异常处理是*不同的*.不要以为你知道什么是"更好". (3认同)

mva*_*lla 25

是的,这是一个旧线程,但是当我在google搜索答案时,我经常会找到旧线程,所以我想我会添加一些有用的东西.

如果您使用的是Visual Studio 2012,则可以使用内置工具来允许IDE级别"抛出"等效项.

如果您使用XML文档注释,如上所述,那么您可以使用<exception>标记来指定方法或类抛出的异常类型,以及有关何时或为何抛出它的信息.

例:

    /// <summary>This method throws an exception.</summary>
    /// <param name="myPath">A path to a directory that will be zipped.</param>
    /// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
    public void FooThrowsAnException (string myPath)
    {
        // This will throw an IO exception
        ZipFile.CreateFromDirectory(myPath);
    }
Run Code Online (Sandbox Code Playgroud)

  • OP,这是你的答案.我猜,但JAVA的'throws`可能对运行时没有任何意义,除了为开发人员提供信息.同样,@ mvanella在这里指出的是C#完全相同的方式.我假设你已经知道这个"xml文档"有更重要的目的.我知道这个帖子已经过时了. (3认同)
  • Java 异常总是在调用链中冒泡,这就是异常的作用。唯一的……例外,请原谅双关语,是经常吃它们的 lambda。java 的不同之处在于存在检查异常。编译器将强制您“检查”异常或在链上的每一步重新抛出异常。在异常一直冒泡通过 main 方法之后,JVM 最后打印堆栈跟踪作为最后的手段。 (3认同)
  • 实际上,Java 不会冒泡异常,除非在“ throws”子句中显式指定或由“ throw”命令抛出。这意味着如果发生 RunTimeException 并且未在发生 RunTimeException 的同一方法中进行处理,则执行将在那里停止。 (2认同)

And*_*s_D 18

以下是我在bytes.com上资助的类似问题的答案:

简短的回答是否定的,C#中没有经过检查的异常.该语言的设计者在本次访谈中讨论了这个决定:

http://www.artima.com/intv/handcuffs.html

最接近的是使用XML文档中的标记,并使用您的代码/程序集分发NDoc生成的文档,以便其他人可以看到您抛出的异常(这正是MS在MSDN文档中所做的那样).您不能依赖编译器来告诉您未处理的异常,但是,您可能习惯于在java中使用.


Tob*_*ias 7

在浏览完大多数答案之后,我想补充一些想法。

  1. 依靠XML文档注释并期望其他人依赖它是一个糟糕的选择。我遇到的大多数C#代码都没有完全和XML文档注释一致地记录方法。还有一个更大的问题,就是在C#中没有检查异常,如何记录方法抛出的所有异常,以便API用户知道如何单独处理所有异常?记住,您只知道在实现中使用throw关键字抛出自己的代码。您在方法实现中使用的API可能还会引发您不知道的异常,因为它们可能没有记录,并且您在实现中没有对其进行处理,因此它们会在面对您的调用方时爆炸方法。换一种说法,

  2. Andreas在这里回答了有关C#设计团队为何决定不检查异常的答案,并与Anders Hejlsberg进行了访谈。对原始问题的最终回答隐藏在该采访中:

程序员通过在各处编写try finally来保护代码,因此,如果发生异常,他们将正确退出,但是实际上他们对处理异常并不感兴趣。

换句话说,没有人会对特定API预期会发生什么样的异常感兴趣,因为您总是会无处不在地捕获所有异常。而且,如果您要真正关心特定的异常,则如何处理它们取决于您自己,而不是由使用Java throws关键字之类的方法定义方法签名的人来决定,从而强制对API用户进行特定的异常处理。

-

就个人而言,我在这里被撕裂了。我同意安德斯(Anders)的观点,即检查异常不会解决问题,而不会添加新的不同问题。就像XML文档注释一样,我很少看到C#代码将所有内容包装在try finally块中。在我看来,虽然这确实是您唯一的选择,但似乎是一种很好的做法。