Skip to content

Commit 846b0c5

Browse files
committed
refactor: Check for duplicates in one pass-through
1 parent cc9f2cb commit 846b0c5

File tree

1 file changed

+21
-46
lines changed

1 file changed

+21
-46
lines changed

src/bunit/ComponentParameterCollection.cs

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ public class ComponentParameterCollection : ICollection<ComponentParameter>, IRe
99
{
1010
private static readonly MethodInfo CreateTemplateWrapperMethod = GetCreateTemplateWrapperMethod();
1111
private static readonly Type CascadingValueType = typeof(CascadingValue<>);
12-
private List<ComponentParameter>? parameters;
12+
private readonly List<ComponentParameter> parameters = new();
1313

1414
/// <summary>
1515
/// Gets the number of <see cref="ComponentParameter"/> in the collection.
1616
/// </summary>
17-
public int Count => parameters?.Count ?? 0;
17+
public int Count => parameters.Count;
1818

1919
/// <inheritdoc />
20-
public bool IsReadOnly { get; }
20+
public bool IsReadOnly => false;
2121

2222
/// <summary>
2323
/// Adds a <paramref name="item"/> to the collection.
@@ -28,9 +28,6 @@ public void Add(ComponentParameter item)
2828
if (item.Name is null && item.Value is null)
2929
throw new ArgumentException("A component parameter without a name and value is not valid.", nameof(item));
3030

31-
if (parameters is null)
32-
parameters = new List<ComponentParameter>();
33-
3431
parameters.Add(item);
3532
}
3633

@@ -53,16 +50,16 @@ public void Add(IEnumerable<ComponentParameter> parameters)
5350
/// </summary>
5451
/// <param name="item">Parameter to check with.</param>
5552
/// <returns>True if <paramref name="item"/> is in the collection, false otherwise.</returns>
56-
public bool Contains(ComponentParameter item) => parameters?.Contains(item) ?? false;
53+
public bool Contains(ComponentParameter item) => parameters.Contains(item);
5754

5855
/// <inheritdoc/>
59-
public void Clear() => parameters?.Clear();
56+
public void Clear() => parameters.Clear();
6057

6158
/// <inheritdoc/>
62-
public void CopyTo(ComponentParameter[] array, int arrayIndex) => parameters?.CopyTo(array, arrayIndex);
59+
public void CopyTo(ComponentParameter[] array, int arrayIndex) => parameters.CopyTo(array, arrayIndex);
6360

6461
/// <inheritdoc/>
65-
public bool Remove(ComponentParameter item) => parameters?.Remove(item) ?? false;
62+
public bool Remove(ComponentParameter item) => parameters.Remove(item);
6663

6764
/// <summary>
6865
/// Creates a <see cref="RenderFragment"/> that will render a
@@ -108,9 +105,6 @@ void AddComponent(RenderTreeBuilder builder)
108105

109106
void AddAttributes(RenderTreeBuilder builder)
110107
{
111-
if (parameters is null)
112-
return;
113-
114108
var attrCount = 100;
115109

116110
foreach (var pgroup in parameters.Where(x => !x.IsCascadingValue).GroupBy(x => x.Name, StringComparer.Ordinal))
@@ -148,7 +142,7 @@ void AddAttributes(RenderTreeBuilder builder)
148142

149143
var groupType = groupObject?.GetType();
150144

151-
if (groupType != null && groupType.IsGenericType && groupType.GetGenericTypeDefinition() == typeof(RenderFragment<>))
145+
if (groupType is { IsGenericType: true } && groupType.GetGenericTypeDefinition() == typeof(RenderFragment<>))
152146
{
153147
builder.AddAttribute(
154148
attrCount++,
@@ -164,49 +158,30 @@ void AddAttributes(RenderTreeBuilder builder)
164158

165159
Queue<(ComponentParameter Parameter, Type Type)> GetCascadingValues()
166160
{
167-
var cascadingValues = parameters?.Where(x => x.IsCascadingValue)
161+
var cascadingValues = parameters
162+
.Where(x => x.IsCascadingValue)
168163
.Select(x => (Parameter: x, Type: GetCascadingValueType(x)))
169-
.ToArray() ?? Array.Empty<(ComponentParameter Parameter, Type Type)>();
164+
.ToArray();
170165

171-
// Detect duplicated unnamed values
172-
for (var i = 0; i < cascadingValues.Length; i++)
166+
var duplicate = cascadingValues
167+
.GroupBy(x => new { x.Type, x.Parameter.Name })
168+
.FirstOrDefault(g => g.Count() > 1);
169+
170+
if (duplicate is not null)
173171
{
174-
for (var j = i + 1; j < cascadingValues.Length; j++)
175-
{
176-
if (cascadingValues[i].Type == cascadingValues[j].Type)
177-
{
178-
var iName = cascadingValues[i].Parameter.Name;
179-
if (iName is null)
180-
{
181-
var cascadingValueType = cascadingValues[i].Type.GetGenericArguments()[0];
182-
throw new ArgumentException($"Two or more unnamed cascading values with the type '{cascadingValueType.Name}' was added. " +
183-
$"Only add one unnamed cascading value of the same type.");
184-
}
172+
var name = duplicate.Key.Name;
173+
var type = duplicate.First().Type.GetGenericArguments()[0];
185174

186-
if (iName.Equals(cascadingValues[j].Parameter.Name, StringComparison.Ordinal))
187-
{
188-
throw new ArgumentException($"Two or more named cascading values with the name '{iName}' and the same type was added. " +
189-
$"Only add one named cascading value with the same name and type.");
190-
}
191-
}
192-
}
175+
throw new ArgumentException($"Two or more unnamed cascading values with the type '{name ?? type.Name}' was added. " +
176+
$"Only add one unnamed cascading value of the same type.");
193177
}
194178

195179
return new Queue<(ComponentParameter Parameter, Type Type)>(cascadingValues);
196180
}
197181
}
198182

199183
/// <inheritdoc/>
200-
public IEnumerator<ComponentParameter> GetEnumerator()
201-
{
202-
if (parameters is not null)
203-
{
204-
for (var i = 0; i < parameters.Count; i++)
205-
{
206-
yield return parameters[i];
207-
}
208-
}
209-
}
184+
public IEnumerator<ComponentParameter> GetEnumerator() => parameters.GetEnumerator();
210185

211186
/// <inheritdoc/>
212187
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();

0 commit comments

Comments
 (0)