Overview
ℹ️ Important
Availability: C# 12
Use collection expressions to create common collection values. This syntax can be assigned to many different collection types. It contains
a sequence of elements between [
and ]
.
Usage
Collection expressions can be used across many constructs:
// In a variable declaration:
Span<string> weekDays = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
// To initialize a private field:
private static readonly ImmutableArray<string> _months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
// To initialize a property with an expression body:
public IEnumerable<int> MaxDays => [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
public int Sum(IEnumerable<int> values) => values.Sum();
public void Example()
{
// As a parameter:
int sum = Sum([1, 2, 3, 4, 5]);
}
You can also use variables as the elements of the collection expression:
string hydrogen = "H";
string helium = "He";
string lithium = "Li";
string beryllium = "Be";
string boron = "B";
string carbon = "C";
string nitrogen = "N";
string oxygen = "O";
string fluorine = "F";
string neon = "Ne";
string[] elements = [ hydrogen, helium, lithium, beryllium, boron, carbon, nitrogen, oxygen, fluorine, neon ];
Spread Elements
A spread element ..
can be used to inline collection values in a collection expression:
string[] vowels = [ "a", "e", "i", "o", "u" ];
string[] consonants = [ "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "z" ];
string[] alphabet = [ ..vowels, ..consonants, "y" ];
Restrictions
Collection expressions cannot be used:
- Where a compile-time constant is expected
- As the default value for a method argument
Creating Collection Types that Support Collection Expressions
- Write a
Create
method that:- Returns an object of the collection type
- Takes a single parameter of the element type
- Add the
[CollectionBuilder]
attribute to the collection type
Consider this LineBuffer
type:
// #2: The attribute added to the collection type and providing the name of the Create method as a parameter:
[CollectionBuilder(typeof(LineBufferBuilder), "Create")]
public class LineBuffer : IEnumerable<char>
{
private readonly char[] _buffer = new char[80];
public LineBuffer(ReadOnlySpan<char> buffer)
{
int number = (_buffer.Length < buffer.Length) ? _buffer.Length : buffer.Length;
for (int i = 0; i < number; i++)
{
_buffer[i] = buffer[i];
}
}
public IEnumerator<char> GetEnumerator() => _buffer.AsEnumerable<char>().GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _buffer.GetEnumerator();
// ...
}
internal static class LineBufferBuilder
{
// #1: A Create() method that:
// #1.1: returns an object of the collection type (LineBuffer)
// #1.2: takes a single parameter of the element type (ReadOnlySpan<char>)
internal static LineBuffer Create(ReadOnlySpan<char> values) => new LineBuffer(values);
}