rory.ap
rory.ap

Reputation: 35318

There is no target type for the collection expression

Using C# 12's new collection expressions, I cannot do something like this:

if (["blue", "red", "foo"].Any((x) =>
{
    ...
})) 

It gives a CS9172 compiler error "There is no target type for the collection expression." Instead of ["blue", "red", "foo"], I have to do new[] { "blue", "red", "foo" } -- the pre-C# 12 way, which doesn't have to specify the type.

Clearly that collection expression contains only one type. Is there a technical reason why the compiler cannot determine the type? That would be a very succinct and useful way to use that new feature if it were possible.

Upvotes: 22

Views: 5432

Answers (2)

Guru Stron
Guru Stron

Reputation: 143088

This is how the feature was designed. There is no "natural type" (at least at the moment) for collection expressions (as for quite some time there was none for lambda expressions). As the doc says:

A collection expression is a terse syntax that, when evaluated, can be assigned to many different collection types.

If you provide a type the code will compile. For example (though it kind of beats the purpose of using collection expressions but still):

if (((string[])["blue", "red", "foo"]).Any((x) => true))
{
   ...
}

Demo @sharplab.io

The conversion rules are defined in the Conversions section of the docs.

Upvotes: 25

Blindy
Blindy

Reputation: 67447

While what the other answer says is true, there was discussion about giving collection expressions a contextual natural type, it just wasn't agreed on what that type should be in all circumstances.

In your case the type you want is ReadOnlySpan<string>, not string[], because the former doesn't create a temporary array object for the GC to clean up at a later point for no reason. Note the difference in IL between the two, the span version uses a struct defined specifically for this collection, and so doesn't allocate any GC objects.

Upvotes: 7

Related Questions