@@ -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