C#: Any way to suppress compiler errors similar to

2019-06-17 06:41发布

问题:

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?

回答1:

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).



回答2:

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.



回答3:

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.