11using System ;
22using System . Collections . Generic ;
3- using System . Linq ;
43using System . Reflection ;
54using JetBrains . Annotations ;
65
@@ -14,33 +13,32 @@ public static class AnyClassUtility
1413 {
1514 public static readonly BindingFlags DefaultBindingFlags = BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic ;
1615
16+ [ Pure ]
17+ public static IReadOnlyList < FieldInfo > GetOrderedFields < T > ( )
18+ {
19+ return GetOrderedFields ( typeof ( T ) ) ;
20+ }
21+
1722 [ Pure , ItemNotNull ]
18- public static T [ ] Reorder < T > ( this T [ ] array , IEnumerable < int > newIndices )
23+ public static IReadOnlyList < T > Reorder < T > ( [ ItemNotNull ] IEnumerable < T > items , Func < T , int ? > getOrder )
1924 {
20- var newArray = new T [ array . Length ] ;
21- var index = 0 ;
22- foreach ( var newIndex in newIndices )
25+ var orderedItems = new List < T > ( ) ;
26+ var sortedCache = new SortedList < int , T > ( ) ;
27+ foreach ( var item in items )
2328 {
24- if ( array [ index ] == null ) throw new ArgumentException ( $ "element of { nameof ( array ) } cannot be null" , nameof ( array ) ) ;
25- newArray [ newIndex ] = array [ index ] ;
26- index ++ ;
29+ var order = getOrder ( item ) ;
30+ if ( order . HasValue ) sortedCache . Add ( order . Value , item ) ;
31+ else orderedItems . Add ( item ) ;
2732 }
28- if ( index != array . Length )
29- throw new ArgumentException ( $ "{ nameof ( array ) } ({ array . Length } ) and { nameof ( newIndices ) } ({ index } ) must have same count of elements", nameof ( newIndices ) ) ;
30- return array ;
33+ foreach ( var ( order , item ) in sortedCache ) orderedItems . Insert ( Math . Min ( order , orderedItems . Count ) , item ) ;
34+ return orderedItems ;
3135 }
3236
3337 [ Pure ]
34- public static FieldInfo [ ] GetOrderedFields < T > ( )
38+ public static IReadOnlyList < FieldInfo > GetOrderedFields ( Type type )
3539 {
36- var fields = typeof ( T ) . GetFields ( DefaultBindingFlags ) ;
37- var newIndices = fields
38- . Select ( ( f , i ) => ( index : i , order : f . GetCustomAttribute < AnySerializeFieldOrderAttribute > ( ) ? . Order ?? i ) )
39- . OrderBy ( t => t . order )
40- . Select ( t => t . index )
41- ;
42- fields = fields . Reorder ( newIndices ) ;
43- return fields ;
40+ var fields = type . GetFields ( DefaultBindingFlags ) ;
41+ return Reorder ( fields , field => field . GetCustomAttribute < AnySerializeFieldOrderAttribute > ( ) ? . Order ) ;
4442 }
4543 }
4644}
0 commit comments