Skip to content

Commit 26f4907

Browse files
committed
Code refactoring, improved nullability annotations
1 parent 3f752a8 commit 26f4907

File tree

1 file changed

+75
-91
lines changed

1 file changed

+75
-91
lines changed

Microsoft.Toolkit/Collections/ObservableGroupedCollectionExtensions.cs

Lines changed: 75 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public static ObservableGroup<TKey, TValue> First<TKey, TValue>(this ObservableG
3232

3333
if (group is null)
3434
{
35+
static void ThrowArgumentExceptionForKeyNotFound()
36+
{
37+
throw new InvalidOperationException("The requested key was not present in the collection");
38+
}
39+
3540
ThrowArgumentExceptionForKeyNotFound();
3641
}
3742

@@ -63,20 +68,16 @@ public static ObservableGroup<TKey, TValue> First<TKey, TValue>(this ObservableG
6368
return null;
6469
}
6570

71+
// Fallback method
72+
[MethodImpl(MethodImplOptions.NoInlining)]
73+
static ObservableGroup<TKey, TValue>? FirstOrDefaultWithLinq(ObservableGroupedCollection<TKey, TValue> source, TKey key)
74+
{
75+
return source.FirstOrDefault(group => EqualityComparer<TKey>.Default.Equals(group.Key, key));
76+
}
77+
6678
return FirstOrDefaultWithLinq(source, key);
6779
}
6880

69-
/// <summary>
70-
/// Slow path for <see cref="First{TKey,TValue}"/>.
71-
/// </summary>
72-
[Pure]
73-
[MethodImpl(MethodImplOptions.NoInlining)]
74-
private static ObservableGroup<TKey, TValue>? FirstOrDefaultWithLinq<TKey, TValue>(
75-
ObservableGroupedCollection<TKey, TValue> source,
76-
TKey key)
77-
where TKey : notnull
78-
=> source.FirstOrDefault(group => EqualityComparer<TKey>.Default.Equals(group.Key, key));
79-
8081
/// <summary>
8182
/// Return the element at position <paramref name="index"/> from the first group with <paramref name="key"/> key.
8283
/// </summary>
@@ -106,7 +107,7 @@ public static TValue ElementAt<TKey, TValue>(
106107
/// <param name="index">The index of the item from the targeted group.</param>
107108
/// <returns>The element or default(TValue) if it does not exist.</returns>
108109
[Pure]
109-
public static TValue ElementAtOrDefault<TKey, TValue>(
110+
public static TValue? ElementAtOrDefault<TKey, TValue>(
110111
this ObservableGroupedCollection<TKey, TValue> source,
111112
TKey key,
112113
int index)
@@ -117,7 +118,7 @@ public static TValue ElementAtOrDefault<TKey, TValue>(
117118
if (group is null ||
118119
(uint)index >= (uint)group.Count)
119120
{
120-
return default!;
121+
return default;
121122
}
122123

123124
return group[index];
@@ -285,27 +286,24 @@ public static void RemoveGroup<TKey, TValue>(
285286
}
286287
else
287288
{
288-
RemoveGroupWithLinq(source, key);
289-
}
290-
}
291-
292-
/// <summary>
293-
/// Slow path for <see cref="RemoveGroup{TKey,TValue}"/>.
294-
/// </summary>
295-
[MethodImpl(MethodImplOptions.NoInlining)]
296-
private static void RemoveGroupWithLinq<TKey, TValue>(ObservableGroupedCollection<TKey, TValue> source, TKey key)
297-
where TKey : notnull
298-
{
299-
var index = 0;
300-
foreach (var group in source)
301-
{
302-
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
289+
// Fallback method
290+
[MethodImpl(MethodImplOptions.NoInlining)]
291+
static void RemoveGroupWithLinq(ObservableGroupedCollection<TKey, TValue> source, TKey key)
303292
{
304-
source.RemoveAt(index);
305-
return;
293+
var index = 0;
294+
foreach (var group in source)
295+
{
296+
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
297+
{
298+
source.RemoveAt(index);
299+
return;
300+
}
301+
302+
index++;
303+
}
306304
}
307305

308-
index++;
306+
RemoveGroupWithLinq(source, key);
309307
}
310308
}
311309

@@ -348,37 +346,34 @@ public static void RemoveItem<TKey, TValue>(
348346
}
349347
else
350348
{
351-
RemoveItemWithLinq(source, key, item, removeGroupIfEmpty);
352-
}
353-
}
354-
355-
/// <summary>
356-
/// Slow path for <see cref="RemoveItem{TKey,TValue}"/>.
357-
/// </summary>
358-
[MethodImpl(MethodImplOptions.NoInlining)]
359-
private static void RemoveItemWithLinq<TKey, TValue>(
360-
ObservableGroupedCollection<TKey, TValue> source,
361-
TKey key,
362-
TValue item,
363-
bool removeGroupIfEmpty)
364-
where TKey : notnull
365-
{
366-
var index = 0;
367-
foreach (var group in source)
368-
{
369-
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
349+
// Fallback method
350+
[MethodImpl(MethodImplOptions.NoInlining)]
351+
static void RemoveItemWithLinq(
352+
ObservableGroupedCollection<TKey, TValue> source,
353+
TKey key,
354+
TValue item,
355+
bool removeGroupIfEmpty)
370356
{
371-
if (group.Remove(item) &&
372-
removeGroupIfEmpty &&
373-
group.Count == 0)
357+
var index = 0;
358+
foreach (var group in source)
374359
{
375-
source.RemoveAt(index);
376-
}
360+
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
361+
{
362+
if (group.Remove(item) &&
363+
removeGroupIfEmpty &&
364+
group.Count == 0)
365+
{
366+
source.RemoveAt(index);
367+
}
368+
369+
return;
370+
}
377371

378-
return;
372+
index++;
373+
}
379374
}
380375

381-
index++;
376+
RemoveItemWithLinq(source, key, item, removeGroupIfEmpty);
382377
}
383378
}
384379

@@ -422,46 +417,35 @@ public static void RemoveItemAt<TKey, TValue>(
422417
}
423418
else
424419
{
425-
RemoveItemAtWithLinq(source, key, index, removeGroupIfEmpty);
426-
}
427-
}
428-
429-
/// <summary>
430-
/// Slow path for <see cref="RemoveItemAt{TKey,TValue}"/>.
431-
/// </summary>
432-
[MethodImpl(MethodImplOptions.NoInlining)]
433-
private static void RemoveItemAtWithLinq<TKey, TValue>(
434-
ObservableGroupedCollection<TKey, TValue> source,
435-
TKey key,
436-
int index,
437-
bool removeGroupIfEmpty)
438-
where TKey : notnull
439-
{
440-
var groupIndex = 0;
441-
foreach (var group in source)
442-
{
443-
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
420+
// Fallback method
421+
[MethodImpl(MethodImplOptions.NoInlining)]
422+
static void RemoveItemAtWithLinq(
423+
ObservableGroupedCollection<TKey, TValue> source,
424+
TKey key,
425+
int index,
426+
bool removeGroupIfEmpty)
444427
{
445-
group.RemoveAt(index);
446-
447-
if (removeGroupIfEmpty && group.Count == 0)
428+
var groupIndex = 0;
429+
foreach (var group in source)
448430
{
449-
source.RemoveAt(groupIndex);
450-
}
431+
if (EqualityComparer<TKey>.Default.Equals(group.Key, key))
432+
{
433+
group.RemoveAt(index);
451434

452-
return;
435+
if (removeGroupIfEmpty && group.Count == 0)
436+
{
437+
source.RemoveAt(groupIndex);
438+
}
439+
440+
return;
441+
}
442+
443+
groupIndex++;
444+
}
453445
}
454446

455-
groupIndex++;
447+
RemoveItemAtWithLinq(source, key, index, removeGroupIfEmpty);
456448
}
457449
}
458-
459-
/// <summary>
460-
/// Throws a new <see cref="InvalidOperationException"/> when a key is not found.
461-
/// </summary>
462-
private static void ThrowArgumentExceptionForKeyNotFound()
463-
{
464-
throw new InvalidOperationException("The requested key was not present in the collection");
465-
}
466450
}
467451
}

0 commit comments

Comments
 (0)