Skip to content

Commit 34f82fe

Browse files
authored
Merge pull request #719 from CommunityToolkit/dev/builder-enumerable
Remove unnecessary temporary array allocation
2 parents d6eb5cc + 9c607b0 commit 34f82fe

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

src/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ public static MemberDeclarationSyntax GetPropertySyntax(PropertyInfo propertyInf
961961
.AddArgumentListArguments(
962962
Argument(fieldExpression),
963963
Argument(IdentifierName("value")))),
964-
Block(setterStatements.ToArray()));
964+
Block(setterStatements.AsEnumerable()));
965965

966966
// Prepare the forwarded attributes, if any
967967
ImmutableArray<AttributeListSyntax> forwardedAttributes =

src/CommunityToolkit.Mvvm.SourceGenerators/Helpers/ImmutableArrayBuilder{T}.cs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
using System;
99
using System.Buffers;
10+
using System.Collections;
11+
using System.Collections.Generic;
1012
using System.Collections.Immutable;
1113
using System.Diagnostics.CodeAnalysis;
1214
using System.Runtime.CompilerServices;
@@ -88,6 +90,18 @@ public readonly T[] ToArray()
8890
return this.writer!.WrittenSpan.ToArray();
8991
}
9092

93+
/// <summary>
94+
/// Gets an <see cref="IEnumerable{T}"/> instance for the current builder.
95+
/// </summary>
96+
/// <returns>An <see cref="IEnumerable{T}"/> instance for the current builder.</returns>
97+
/// <remarks>
98+
/// The builder should not be mutated while an enumerator is in use.
99+
/// </remarks>
100+
public readonly IEnumerable<T> AsEnumerable()
101+
{
102+
return this.writer!;
103+
}
104+
91105
/// <inheritdoc/>
92106
public override readonly string ToString()
93107
{
@@ -107,7 +121,7 @@ public void Dispose()
107121
/// <summary>
108122
/// A class handling the actual buffer writing.
109123
/// </summary>
110-
private sealed class Writer : IDisposable
124+
private sealed class Writer : ICollection<T>, IDisposable
111125
{
112126
/// <summary>
113127
/// The underlying <typeparamref name="T"/> array.
@@ -142,6 +156,9 @@ public ReadOnlySpan<T> WrittenSpan
142156
get => new(this.array!, 0, this.index);
143157
}
144158

159+
/// <inheritdoc/>
160+
bool ICollection<T>.IsReadOnly => true;
161+
145162
/// <inheritdoc cref="ImmutableArrayBuilder{T}.Add"/>
146163
public void Add(T value)
147164
{
@@ -173,6 +190,48 @@ public void Dispose()
173190
}
174191
}
175192

193+
/// <inheritdoc/>
194+
void ICollection<T>.Clear()
195+
{
196+
throw new NotSupportedException();
197+
}
198+
199+
/// <inheritdoc/>
200+
bool ICollection<T>.Contains(T item)
201+
{
202+
throw new NotSupportedException();
203+
}
204+
205+
/// <inheritdoc/>
206+
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
207+
{
208+
Array.Copy(this.array!, 0, array, arrayIndex, this.index);
209+
}
210+
211+
/// <inheritdoc/>
212+
IEnumerator<T> IEnumerable<T>.GetEnumerator()
213+
{
214+
T?[] array = this.array!;
215+
int length = this.index;
216+
217+
for (int i = 0; i < length; i++)
218+
{
219+
yield return array[i]!;
220+
}
221+
}
222+
223+
/// <inheritdoc/>
224+
IEnumerator IEnumerable.GetEnumerator()
225+
{
226+
return ((IEnumerable<T>)this).GetEnumerator();
227+
}
228+
229+
/// <inheritdoc/>
230+
bool ICollection<T>.Remove(T item)
231+
{
232+
throw new NotSupportedException();
233+
}
234+
176235
/// <summary>
177236
/// Ensures that <see cref="array"/> has enough free space to contain a given number of new items.
178237
/// </summary>

0 commit comments

Comments
 (0)