dotnet / dotnet/roslyn

Need an API to get the 'iteration type' of a type.

Open
#77,926 6 comments 0 reactions 0 assignees View on GitHub
api-approved Area-Compilers Concept-API Feature Request help wanted
Dominant language
C#
Stars
20.7k
Forks
4.3k
PR merge metrics
PR metrics pending

Description

## Background and Motivation

The IDE has a lot of code for dealing with collection expressions, and just normal collection types, especially around trying to manipulate them and determine if a change from a non-collection to a collection will be legal. This is challenging as we need to ultimately figure out what the starting iteration type is, as well as the final collection-element type, and if things like the elements will be legal given that type.

Determining a iteration type is *non trivial*. Including having to special case a bunch of types. Having to figure out the 'enumerator' pattern if it is there. Having to handle inline arrays. Having to handle spans. Handling IEnumerable, etc. etc.

The IDE has hacked up a bunch of heuristics. But we really need a concrete way of answering this for real.

## Proposed API

Either:

```c#

// In MS.CA.dll

namespace MS.CA;

public class SemanticModel
{
// This is the iteration type that is used in C# foreach, and VB `for each`
// null-return if cannot be determined.
public ITypeSymbol? GetIterationType(
int position, ITypeSymbol type, CancellationToken cancellationToken = default);
}
```

This API is defined on top of the SemanticModel, along with a position, because extension-methods may be involved in determining the element type.

--

Note: this likely will utilize https://github.com/dotnet/roslyn/blob/b570dc0b9e4234c93dfc3195bdaf660abc394715/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs#L1702 to implement this functionality.

Note that the syntax node here is used to just get the right binder.

Contributor guide

Open the contributing guide

Research direction

Start with the proposed SemanticModel.GetIterationType API and read the referenced CSharp/Portable/Binder/Binder_Conversions.cs implementation around the cited line. Trace how the binder determines foreach iteration types, including extension methods and special cases described in the issue. Done means the API is exposed with the proposed position and cancellation parameters and reliably returns the iteration type or null when it cannot be determined.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.