7

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

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

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

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

4

3 回答 3

10

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

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

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

于 2011-02-14T23:24:38.423 回答
7

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

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

但是,我怀疑这是预期的行为,因为编译器不知道您正在调用的方法将始终抛出,并且即使不是不可能,也很难以可预测的方式确定任何可能的调用树(想象一下,如果您调用一连串的 20 种方法,然后以 throw 结束)。

于 2011-02-14T23:05:21.507 回答
3

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

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

更新:理论上,可以扩展 C# 以允许没有返回路径的方法。Eric Lippert 在评论 Jon Skeet 的回答时提到了这一点

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

于 2011-02-14T23:17:30.640 回答