@@ -17,7 +17,7 @@ public static PropertyEnumerable GetPropertiesIncludingInherited(
17
17
[ DynamicallyAccessedMembers ( Component ) ] Type type ,
18
18
BindingFlags bindingFlags )
19
19
{
20
- var dictionary = new Dictionary < string , OneOrMoreProperties > ( StringComparer . Ordinal ) ;
20
+ var dictionary = new Dictionary < string , object > ( StringComparer . Ordinal ) ;
21
21
22
22
Type ? currentType = type ;
23
23
@@ -28,12 +28,21 @@ public static PropertyEnumerable GetPropertiesIncludingInherited(
28
28
{
29
29
if ( ! dictionary . TryGetValue ( property . Name , out var others ) )
30
30
{
31
- others = new OneOrMoreProperties { Single = property } ;
32
- dictionary . Add ( property . Name , others ) ;
31
+ dictionary . Add ( property . Name , property ) ;
33
32
}
34
33
else if ( ! IsInheritedProperty ( property , others ) )
35
34
{
36
- others . Add ( property ) ;
35
+ List < PropertyInfo > many ;
36
+ if ( others is PropertyInfo single )
37
+ {
38
+ many = new List < PropertyInfo > { single } ;
39
+ dictionary [ property . Name ] = many ;
40
+ }
41
+ else
42
+ {
43
+ many = ( List < PropertyInfo > ) others ;
44
+ }
45
+ many . Add ( property ) ;
37
46
}
38
47
}
39
48
@@ -43,15 +52,15 @@ public static PropertyEnumerable GetPropertiesIncludingInherited(
43
52
return new PropertyEnumerable ( dictionary ) ;
44
53
}
45
54
46
- private static bool IsInheritedProperty ( PropertyInfo property , OneOrMoreProperties others )
55
+ private static bool IsInheritedProperty ( PropertyInfo property , object others )
47
56
{
48
- if ( others . Single is not null )
57
+ if ( others is PropertyInfo single )
49
58
{
50
- return others . Single . GetMethod ? . GetBaseDefinition ( ) == property . GetMethod ? . GetBaseDefinition ( ) ;
59
+ return single . GetMethod ? . GetBaseDefinition ( ) == property . GetMethod ? . GetBaseDefinition ( ) ;
51
60
}
52
61
53
- Debug . Assert ( others . Many is not null ) ;
54
- foreach ( var other in CollectionsMarshal . AsSpan ( others . Many ) )
62
+ var many = ( List < PropertyInfo > ) others ;
63
+ foreach ( var other in CollectionsMarshal . AsSpan ( many ) )
55
64
{
56
65
if ( other . GetMethod ? . GetBaseDefinition ( ) == property . GetMethod ? . GetBaseDefinition ( ) )
57
66
{
@@ -62,28 +71,11 @@ private static bool IsInheritedProperty(PropertyInfo property, OneOrMoreProperti
62
71
return false ;
63
72
}
64
73
65
- public struct OneOrMoreProperties
66
- {
67
- public PropertyInfo ? Single ;
68
- public List < PropertyInfo > ? Many ;
69
-
70
- public void Add ( PropertyInfo property )
71
- {
72
- if ( Many is null )
73
- {
74
- Many ??= new ( ) { Single ! } ;
75
- Single = null ;
76
- }
77
-
78
- Many . Add ( property ) ;
79
- }
80
- }
81
-
82
74
public ref struct PropertyEnumerable
83
75
{
84
76
private readonly PropertyEnumerator _enumerator ;
85
77
86
- public PropertyEnumerable ( Dictionary < string , OneOrMoreProperties > dictionary )
78
+ public PropertyEnumerable ( Dictionary < string , object > dictionary )
87
79
{
88
80
_enumerator = new PropertyEnumerator ( dictionary ) ;
89
81
}
@@ -94,16 +86,27 @@ public PropertyEnumerable(Dictionary<string, OneOrMoreProperties> dictionary)
94
86
public ref struct PropertyEnumerator
95
87
{
96
88
// Do NOT make this readonly, or MoveNext will not work
97
- private Dictionary < string , OneOrMoreProperties > . Enumerator _dictionaryEnumerator ;
89
+ private Dictionary < string , object > . Enumerator _dictionaryEnumerator ;
98
90
private Span < PropertyInfo > . Enumerator _spanEnumerator ;
99
91
100
- public PropertyEnumerator ( Dictionary < string , OneOrMoreProperties > dictionary )
92
+ public PropertyEnumerator ( Dictionary < string , object > dictionary )
101
93
{
102
94
_dictionaryEnumerator = dictionary . GetEnumerator ( ) ;
103
95
_spanEnumerator = Span < PropertyInfo > . Empty . GetEnumerator ( ) ;
104
96
}
105
97
106
- public PropertyInfo Current => _spanEnumerator . Current ;
98
+ public PropertyInfo Current
99
+ {
100
+ get
101
+ {
102
+ if ( _dictionaryEnumerator . Current . Value is PropertyInfo property )
103
+ {
104
+ return property ;
105
+ }
106
+
107
+ return _spanEnumerator . Current ;
108
+ }
109
+ }
107
110
108
111
public bool MoveNext ( )
109
112
{
@@ -118,11 +121,14 @@ public bool MoveNext()
118
121
}
119
122
120
123
var oneOrMoreProperties = _dictionaryEnumerator . Current . Value ;
121
- var span = oneOrMoreProperties . Single is { } property ?
122
- MemoryMarshal . CreateSpan ( ref property , 1 ) :
123
- CollectionsMarshal . AsSpan ( oneOrMoreProperties . Many ) ;
124
+ if ( oneOrMoreProperties is PropertyInfo )
125
+ {
126
+ _spanEnumerator = Span < PropertyInfo > . Empty . GetEnumerator ( ) ;
127
+ return true ;
128
+ }
124
129
125
- _spanEnumerator = span . GetEnumerator ( ) ;
130
+ var many = ( List < PropertyInfo > ) oneOrMoreProperties ;
131
+ _spanEnumerator = CollectionsMarshal . AsSpan ( many ) . GetEnumerator ( ) ;
126
132
var moveNext = _spanEnumerator . MoveNext ( ) ;
127
133
Debug . Assert ( moveNext , "We expect this to at least have one item." ) ;
128
134
return moveNext ;
0 commit comments