runtime: [New rule] Notify that foreach may throw InvalidCastException

I tried to move it to StyleCop, but it got rejected there as well: https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3307#issuecomment-785952062 (as they don’t deal with analyzers that prevent exception in any way. only style related ones)

I agree that including this in roslyn as a warning will break a lot of existing code, but I still feel like this analyzer will bring value to .Net community, so it shouldn’t be rejected outright.

False positives

There was a lot of concern about false positive rate, but after some investigation, I believe it can be greatly reduced.

Regarding what is and isn’t a false positive, there are too two groups so far:

  • object collections (like ArrayList). A lot of code is already written for them and it expects foreach to cast them to some type, so there shouldn’t be any surprise that it performs explicit cast in their case. I excluded such collections from this analyzer, so this is no longer a false positive. I’m not sure if generic collections with object as type argument (List<object>) should be included in this bucket though. Would like to hear any thoughts on this.
  • Collections that always return one type. For example:
    foreach (string item in GenerateSequence()) { }
    
    IEnumerable<IComparable> GenerateSequence() { }
    
    Here’s an example from dotnet/runtime. Here explicit cast is performed since Instantiation returns TypeDesc and GenericParameterDesc is derived from TypeDesc. Should it be flagged with this analyzer to manually perform the cast? Also would like to hear any thoughts on this. Here is another example (schema.Includes is XmlSchemaObject)

As for other false positives, I didn’t find any so far (at least in dotnet/runtime nothing is flagged if I exclude everything mentioned above).

Proposal

I propose to include this analyzer into roslyn, but as a suggestion (or at least disabled, if you’ll come to conclusion that is still will be too noisy). So it’s available to all users out of the box.

People seemed to be kinda ok with suggestion severity:

CC: @jmarolf, @stephentoub, @AraHaan, @GrabYourPitchforks, @mavasani

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 8
  • Comments: 21 (8 by maintainers)

Most upvoted comments

@jmarolf, I don’t think it should 😃 It will be a breaking change and such things ain’t welcome by C#. So there’s no need to bother language designers

In this particular case I see the analyzer as a tool that can change something without actually breaking the language

it’s not opinion-based

Sure it is. Per your example, it’s saying that the syntax:

foreach (object o in objects)
{
    int i = (int)o;
    ...
}

is somehow better than the syntax:

foreach (int i in objects)
{
    ...
}

and that the language’s long-standing support for expressing the cast in that simple manner is somehow inferior to being more explicit about it. That is an opinion.