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

发布于 2024-09-14 04:26:25 字数 237 浏览 9 评论 0原文

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

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

如果没有等效的,如何才能达到相同(或相似)的效果?

In Java, the throws keyword allows for a method to declare that it will not handle an exception on its own, but rather throw it to the calling method.

Is there a similar keyword/attribute in C#?

If there is no equivalent, how can you accomplish the same (or a similar) effect?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

草莓酥 2024-09-21 04:26:25

该操作正在询问 Java 的 C# 等效项throws 子句 - 不是 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...
}

翻译为

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

The op is asking about the C# equivalent of Java's throws clause - not the throw keyword. This is used in method signatures in Java to indicate a checked exception can be thrown.

In C#, there is no direct equivalent of a Java checked exception. C# has no equivalent method signature clause.

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

translates to

// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile() 
{
  ...not explicitly handling System.IO.IOException...
}
荒路情人 2024-09-21 04:26:25

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

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

如果你想处理它然后重新抛出,你可以执行以下操作:

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}

In Java, you must either handle an exception or mark the method as one that may throw it using the throws keyword.

C# does not have this keyword or an equivalent one, as in C#, if you don't handle an exception, it will bubble up, until caught or if not caught it will terminate the program.

If you want to handle it then re-throw you can do the following:

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}
梦巷 2024-09-21 04:26:25

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

如果您使用的是 Visual Studio 2012,则有一个内置工具可用于允许 IDE 级别的“抛出”等效项。

如果您使用 XML 文档注释(如上所述),那么您可以使用 标记指定方法或类引发的异常类型以及有关何时或为什么它被抛出。

例子:

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

Yes this is an old thread, however I frequently find old threads when I am googling answers so I figured I would add something useful that I have found.

If you are using Visual Studio 2012 there is a built in tool that can be used to allow for an IDE level "throws" equivalent.

If you use XML Documentation Comments, as mentioned above, then you can use the <exception> tag to specify the type of exception thrown by the method or class as well as information on when or why it is thrown.

example:

    /// <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);
    }
表情可笑 2024-09-21 04:26:25

这是我刚刚在 上找到的类似问题的答案bytes.com:

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

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

最接近的方法是使用 XML 中的标签
文档,并与您分发 NDoc 生成的文档
代码/程序集,以便其他人可以看到您抛出了哪些异常
(这正是 MS 在 MSDN 文档中所做的)。你不能依赖
但是,编译器会告诉您有关未处理的异常的信息,例如
你可能习惯了java。

Here is an answer to a similar question I just found on bytes.com:

The short answer is no. There are no checked exceptions in C#. The
designer of the language discusses this decision in this interview:

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

The nearest you can get is to use the tags in your XML
documentation, and distribute NDoc generated docs with your
code/assemblies so that other people can see which exceptions you throw
(which is exactly what MS do in the MSDN documentation). You can't rely
on the compiler to tell you about unhandled exceptions, however, like
you may be used to in java.

久伴你 2024-09-21 04:26:25

在浏览完这里的大部分答案后,我想补充一些想法。

  1. 依赖 XML 文档注释并期望其他人依赖是一个糟糕的选择。我遇到的大多数 C# 代码都没有完整地记录方法,并且与 XML 文档注释保持一致。然后还有一个更大的问题,如果 C# 中没有检查异常,您如何记录您的方法抛出的所有异常,以便 API 用户知道如何单独处理它们?请记住,您只知道在实现中使用 throw 关键字自己抛出的那些。您在方法实现中使用的 API 也可能会引发您不知道的异常,因为它们可能没有记录在案,并且您没有在实现中处理它们,因此它们会在您的调用者面前爆炸。方法。换句话说,这些 XML 文档注释并不能替代已检查的异常。

  2. Andreas 在此处的答案中链接了对 Anders Hejlsberg 的采访,了解 C# 设计团队为何决定反对检查异常。对原始问题的最终回答隐藏在该采访中:

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

换句话说,没有人应该对特定 API 会出现什么样的异常感兴趣,因为您总是会在任何地方捕获所有异常。如果您想真正关心特定的异常,那么如何处理它们取决于您,而不是由某人使用 Java throws 关键字定义方法签名,从而强制 API 用户进行特定的异常处理。

——

就我个人而言,我对此感到困惑。我同意 Anders 的观​​点,即如果不添加新的不同问题,检查异常并不能解决问题。就像 XML 文档注释一样,我很少看到 C# 代码将所有内容都包含在 try finally 块中。在我看来,这确实是你唯一的选择,而且似乎是一个很好的做法。

After going through most of the answers here, I'd like to add a couple of thoughts.

  1. Relying on XML Documentation Comments and expecting others to rely on is a poor choice. Most C# code I've come across does not document methods completely and consistently with XML Documentation Comments. And then there's the bigger issue that without checked exceptions in C#, how could you document all exceptions your method throws for the purpose of your API user to know how to handle them all individually? Remember, you only know about the ones you throw yourself with the throw keyword in your implementation. APIs you're using inside your method implementation might also throw exceptions that you don't know about because they might not be documented and you're not handling them in your implementation, so they'll blow up in face of the caller of your method. In other words, these XML documentation comments are no replacement for checked exceptions.

  2. Andreas linked an interview with Anders Hejlsberg in the answers here on why the C# design team decided against checked exceptions. The ultimate response to the original question is hidden in that interview:

The programmers protect their code by writing try finally's everywhere, so they'll back out correctly if an exception occurs, but they're not actually interested in handling the exceptions.

In other words, nobody should be interested in what kind of exception can be expected for a particular API as you're always going to catch all of them everywhere. And if you want to really care about particular exceptions, how to handle them is up to you and not someone defining a method signature with something like the Java throws keyword, forcing particular exception handling on an API user.

--

Personally, I'm torn here. I agree with Anders that having checked exceptions doesn't solve the problem without adding new, different problems. Just like with the XML documentation comments, I rarely see C# code with everything wrapped in try finally blocks. It feels to me though this is indeed your only option and something that seems like a good practice.

别闹i 2024-09-21 04:26:25

实际上,C# 中没有检查异常可以被认为是一件好事,也可以被认为是一件坏事。

我自己认为这是一个很好的解决方案,因为检查的异常给您带来了以下问题:

  1. 技术异常泄漏到业务/域层,因为您无法在低级别正确处理它们。
  2. 它们属于方法签名,但并不总是能很好地配合 API 设计。

因此,在大多数较大的应用程序中,当发生受检查的异常时,您经常会看到以下模式:

try {
    // Some Code
} catch(SomeException ex){
    throw new RuntimeException(ex);
}

这本质上意味着模拟 C#/.NET 处理所有异常的方式。

Actually not having checked exceptions in C# can be considered a good or bad thing.

I myself consider it to be a good solution since checked exceptions provide you with the following problems:

  1. Technical Exceptions leaking to the business/domain layer because you cannot handle them properly on the low level.
  2. They belong to the method signature which doesn't always play nice with API design.

Because of that in most bigger applications you will see the following pattern often when checked Exceptions occur:

try {
    // Some Code
} catch(SomeException ex){
    throw new RuntimeException(ex);
}

Which essentially means emulating the way C#/.NET handles all Exceptions.

呆橘 2024-09-21 04:26:25

您询问的是:

重新抛出异常

public void Method()
{
  try
  {
      int x = 0;
      int sum = 100/x;
  }
  catch(DivideByZeroException e)
  {
      throw;
  }
}

static void Main() 
    {
        string s = null;

        if (s == null) 
        {
            throw new ArgumentNullException();
        }

        Console.Write("The string s is null"); // not executed
    }

You are asking about this :

Re-throwing an Exception

public void Method()
{
  try
  {
      int x = 0;
      int sum = 100/x;
  }
  catch(DivideByZeroException e)
  {
      throw;
  }
}

or

static void Main() 
    {
        string s = null;

        if (s == null) 
        {
            throw new ArgumentNullException();
        }

        Console.Write("The string s is null"); // not executed
    }
箹锭⒈辈孓 2024-09-21 04:26:25

.Net CodeContract EnsuresOnThrow>>< 之间存在一些短暂的相似之处/code>和 java throws 描述符,因为两者都可以向调用者发出信号,作为可以从函数或方法引发的异常类型,尽管两者之间也存在重大差异2:

  • EnsuresOnThrow<> 不仅仅说明可以抛出哪些异常,还规定了保证抛出异常的条件 - 如果以下情况,这在被调用方法中可能是相当繁重的代码:异常情况的识别并不容易。 Java throws 提供了可以抛出哪些异常的指示(即 IMO,.Net 中的焦点位于用于证明 throw 的方法内部,而在 Java 中,焦点转移向调用者确认异常的可能性)。
  • .Net CC 不区分选中与未选中 Java 的例外情况,尽管 CC 手册第 2.2.2 节确实提到了

“仅对调用者认为发生的异常使用异常后置条件
应该作为 API 的一部分”

  • 在 .Net 中,调用者可以确定是否对异常执行任何操作(例如通过禁用合约)。在 Java 中,调用者 必须做某事,即使它为 此处的

代码合同手册

There are some fleeting similarities between the .Net CodeContract EnsuresOnThrow<> and the java throws descriptor, in that both can signal to the caller as the type of exception which could be raised from a function or method, although there are also major differences between the 2:

  • EnsuresOnThrow<> goes beyond just stating which exceptions can be thrown, but also stipulates the conditions under which they are guaranteed to be thrown - this can be quite onerous code in the called method if the exception condition isn't trivial to identify. Java throws provides an indication of which exceptions could be thrown (i.e. IMO the focus in .Net is inside the method which contracts to prove the throw, whereas in Java the focus shifts to the caller to acknowledge the possibility of the exception).
  • .Net CC doesn't make the distinction between Checked vs Unchecked exceptions that Java has, although the CC manual section 2.2.2 does mention to

"use exceptional postconditions only for those exceptions that a caller
should expect as part of the API"

  • In .Net the caller can determine whether or not to do anything with the exception (e.g. by disabling contracts). In Java, the caller must do something, even if it adds a throws for the same exception on its interface.

Code Contracts manual here

〃安静 2024-09-21 04:26:25

对于那些想知道的人,您甚至不需要定义捕获的内容即可将其传递给下一个方法。如果您希望所有错误处理都在一个主线程中,您可以捕获所有内容并将其传递,如下所示:

try {
    //your code here
}
catch {
    //this will throw any exceptions caught by this try/catch
    throw;
}

For those wondering, you do not even need to define what you catch to pass it on to the next method. In case you want all your error handling in one main thread you can just catch everything and pass it on like so:

try {
    //your code here
}
catch {
    //this will throw any exceptions caught by this try/catch
    throw;
}
空城之時有危險 2024-09-21 04:26:25

如果 c# 方法的目的只是抛出异常(就像 js 返回类型所说),我建议只返回该异常。请参阅下面的示例:

public EntityNotFoundException GetEntityNotFoundException(Type entityType, object id)
{
    return new EntityNotFoundException($"The object '{entityType.Name}' with given id '{id}' not found.");
}

如果您想描述异常,可以这样使用摘要:

/// <summary>
/// Gets an entity by <paramref name="id"/>
/// </summary>
/// <exception cref="UserException">Entity not found</exception>
public TEntity GetEntity<TEntity>(string id)
{
    return session.Get<TEntity>(id)
        ?? throw GetEntityNotFoundException(typeof(TEntity), id);
}

If the c# method's purpose is to only throw an exception (like js return type says) I would recommend just return that exception. See the example bellow:

public EntityNotFoundException GetEntityNotFoundException(Type entityType, object id)
{
    return new EntityNotFoundException(
quot;The object '{entityType.Name}' with given id '{id}' not found.");
}

If you would like to describe the exception you can use summary as such:

/// <summary>
/// Gets an entity by <paramref name="id"/>
/// </summary>
/// <exception cref="UserException">Entity not found</exception>
public TEntity GetEntity<TEntity>(string id)
{
    return session.Get<TEntity>(id)
        ?? throw GetEntityNotFoundException(typeof(TEntity), id);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文