C#:有什么方法可以像抑制警告消息一样抑制编译器错误吗?

发布于 2024-10-17 12:49:21 字数 447 浏览 0 评论 0原文

我有以下生成编译器错误的代码:

    Boolean IConvertible.ToBoolean(IFormatProvider provider)
    {
        ThrowHelper.ThrowInvalidCast(typeof(MyType), typeof(Boolean));
    }

编译器抱怨并非所有代码路径都返回值。这里的问题是 ThrowHelper 将总是抛出错误。它是一个调用静态方法的静态类。

我知道我可以在 ThrowHelper 调用后用一个愚蠢的“return true”来满足编译器的要求,但这似乎是不必要的代码。我知道我可以抑制警告消息,但是当我尝试使用 SuppressMessageAttribute 时,它并不能阻止编译器发出抱怨。有什么方法可以仅针对此方法抑制此错误吗?

I have the following code that generates a compiler error:

    Boolean IConvertible.ToBoolean(IFormatProvider provider)
    {
        ThrowHelper.ThrowInvalidCast(typeof(MyType), typeof(Boolean));
    }

The compiler is complaining that not all code paths return a value. The problem here is that ThrowHelper will ALWAYS throw an error. It is a static class calling a static method.

I understand that I can satisfy the compiler with a silly "return true" after the ThrowHelper call, but that seems like unnecessary code. I know I can suppress warning messages, but when I tried to use the SuppressMessageAttribute it doesn't stop the compiler from complaining. Any way to suppress this error only for this method?

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

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

发布评论

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

评论(3

少跟Wǒ拽 2024-10-24 12:49:21

您可以让 ThrowHelper 中的方法仅创建异常,而不实际抛出异常。

Boolean IConvertible.ToBoolean(IFormatProvider provider)
{
    throw ThrowHelper.CreateInvalidCast(typeof(MyType), typeof(Boolean));
}

这也可能会产生更好的堆栈跟踪:它将指向 ToBoolean,而不是 ThrowInvalidCast。

You could have the method in ThrowHelper only create the exception, not actually throw it.

Boolean IConvertible.ToBoolean(IFormatProvider provider)
{
    throw ThrowHelper.CreateInvalidCast(typeof(MyType), typeof(Boolean));
}

This would probably result in a better stack trace as well: it would point at ToBoolean, not at ThrowInvalidCast.

捶死心动 2024-10-24 12:49:21

除了修复错误之外,没有其他方法可以抑制错误。

就其本质而言,错误表明编译器认为它无法生成有效的代码。抑制错误的唯一方法就是修复它们。只需添加所需的 return 语句,然后在 Microsoft Connect 上提出问题,表明你认为编译器弄错了。

然而,我怀疑这是预期的行为,因为编译器不知道您正在调用的方法总是会抛出异常,并且以可预测的方式确定任何可能的调用树将是困难的,如果不是不可能的话(想象一下,如果您调用以 throw 结束之前的 20 个方法链)。

There is no way to suppress an error other than to fix it.

An error, by its nature, is indicating that the compiler believes it cannot generate valid code. The only way to suppress errors is to fix them. Just add the return statement it wants and then raise an issue on Microsoft Connect indicating that you believe the compiler is getting this one wrong.

I suspect, however, that this is expected behaviour as the compiler is not aware that the method you are calling will always throw and to determine that in a predictable manner for any possible call tree would be difficult, if not impossible (imagine if you called a chain of 20 methods before concluding with a throw).

柠檬色的秋千 2024-10-24 12:49:21

一个简单的大脑练习,解释为什么所请求的功能可能会导致问题。想象一下 ThrowHelper.ThrowInvalidCast 是在某个第 3 方库中定义的。您可能知道该方法总是抛出并告诉编译器,或者非常先进的静态分析器可能能够确定该方法总是在编译代码时抛出。

现在其他一些开发人员部署了该库的更新版本。现在该方法并不总是抛出异常。突然出现一种情况,你的方法没有返回路径。为了处理这种情况,编译器(或运行时)必须包含一个备份计划,在这种情况下该怎么做。对于可以通过编写正确的代码轻松修复的问题来说,这是相当大的开销。

更新:理论上,C# 可以扩展以允许没有返回路径的方法。 Eric Lippert 在对 Jon Skeet 的回答的评论中提到 此处

“从不”方法只是一个 void 方法,不允许有可到达的终点或任何返回语句。这解决了编译时的问题。在运行时,验证者有责任确保方法实际上正确地实现其返回类型语义;验证者可以类似地确定没有返回指令并且终点不可到达。

A simple brain exercise why the requested feature could lead to problems. Imagine that ThrowHelper.ThrowInvalidCast is defined in some 3rd-party library. You might know that the method always throws and tell the compiler about it or a very advanced static analyzer might be able to determine that the method always throws at the moment the code is compiled.

Now some other developer deploys an updated version of that library. Now the method doesn't always throw. All of a sudden, there is a case that your method has no return path. Just to handle that case the compiler (or the runtime) would have to include a backup plan what to do in such a situation. Quite a lot of overhead for something that can easily be fixed by writing correct code.

UPDATE: Theoretically, C# could be extended to allow for methods with no return path. Eric Lippert mentioned that in a comment to Jon Skeet's answer here:

A "never" method would simply be a void method that is not allowed to have a reachable end point or any return statements. That solves the problem at compile time. At runtime, it's the verifier's responsibility to ensure that methods actually implement their return type semantics correctly; the verifier could similarly determine that there are no return instructions and that the end point is not reachable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文