Skip to content

Commit aa3dddd

Browse files
Revert "Use array instead of List<T>"
This reverts commit 5ba348f.
1 parent 5ba348f commit aa3dddd

File tree

1 file changed

+24
-46
lines changed

1 file changed

+24
-46
lines changed

src/libraries/Common/src/System/Runtime/InteropServices/ComEventsMethod.cs

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private void PreProcessSignature()
100100
/// Since multicast delegate's built-in chaining supports only chaining instances of the same type,
101101
/// we need to complement this design by using an explicit linked list data structure.
102102
/// </summary>
103-
private DelegateWrapper[] _delegateWrappers = Array.Empty<DelegateWrapper>();
103+
private List<DelegateWrapper> _delegateWrappers = new List<DelegateWrapper>();
104104

105105
private readonly int _dispid;
106106
private ComEventsMethod? _next;
@@ -157,15 +157,15 @@ public bool Empty
157157
{
158158
get
159159
{
160-
DelegateWrapper[] wrappers = _delegateWrappers;
161-
return wrappers.Length == 0;
160+
List<DelegateWrapper> wrappers = _delegateWrappers;
161+
return wrappers.Count == 0;
162162
}
163163
}
164164

165165
public void AddDelegate(Delegate d, bool wrapArgs = false)
166166
{
167-
DelegateWrapper[] wrappers;
168-
DelegateWrapper[] newWrappers;
167+
List<DelegateWrapper> wrappers;
168+
List<DelegateWrapper> newWrappers;
169169
do
170170
{
171171
wrappers = _delegateWrappers;
@@ -180,25 +180,26 @@ public void AddDelegate(Delegate d, bool wrapArgs = false)
180180
}
181181
}
182182

183-
newWrappers = new DelegateWrapper[wrappers.Length + 1];
184-
wrappers.CopyTo(newWrappers, 0);
183+
newWrappers = wrappers.Count == 0
184+
? new List<DelegateWrapper>()
185+
: wrappers.GetRange(0, wrappers.Count);
185186

186-
newWrappers[newWrappers.Length - 1] = new DelegateWrapper(d, wrapArgs);
187+
newWrappers.Add(new DelegateWrapper(d, wrapArgs));
187188
} while (!PublishNewWrappers(newWrappers, wrappers));
188189
}
189190

190191
public void RemoveDelegate(Delegate d, bool wrapArgs = false)
191192
{
192-
DelegateWrapper[] wrappers;
193-
DelegateWrapper[] newWrappers;
193+
List<DelegateWrapper> wrappers;
194+
List<DelegateWrapper> newWrappers;
194195
do
195196
{
196197
wrappers = _delegateWrappers;
197198

198199
// Find delegate wrapper index
199200
int removeIdx = -1;
200201
DelegateWrapper? wrapper = null;
201-
for (int i = 0; i < wrappers.Length; i++)
202+
for (int i = 0; i < wrappers.Count; i++)
202203
{
203204
DelegateWrapper wrapperMaybe = wrappers[i];
204205
if (wrapperMaybe.Delegate.GetType() == d.GetType() && wrapperMaybe.WrapArgs == wrapArgs)
@@ -223,22 +224,22 @@ public void RemoveDelegate(Delegate d, bool wrapArgs = false)
223224
return; // No need to update collection
224225
}
225226

226-
newWrappers = new DelegateWrapper[wrappers.Length - 1];
227-
wrappers.AsSpan(0, removeIdx).CopyTo(newWrappers);
228-
wrappers.AsSpan(removeIdx + 1).CopyTo(newWrappers.AsSpan(removeIdx));
227+
newWrappers = wrappers.GetRange(0, wrappers.Count);
228+
newWrappers.RemoveAt(removeIdx);
229229
} while (!PublishNewWrappers(newWrappers, wrappers));
230230
}
231231

232232
public void RemoveDelegates(Func<Delegate, bool> condition)
233233
{
234-
DelegateWrapper[] wrappers;
235-
DelegateWrapper[] newWrappers;
234+
List<DelegateWrapper> wrappers;
235+
List<DelegateWrapper> newWrappers;
236236
do
237237
{
238238
wrappers = _delegateWrappers;
239239

240+
// Find delegate wrapper indexes. Iterate in reverse such that the list to remove is sorted by high to low index.
240241
List<int> toRemove = new List<int>();
241-
for (int i = 0; i < wrappers.Length; i++)
242+
for (int i = wrappers.Count - 1; i >= 0; i--)
242243
{
243244
DelegateWrapper wrapper = wrappers[i];
244245
Delegate[] invocationList = wrapper.Delegate.GetInvocationList();
@@ -265,43 +266,20 @@ public void RemoveDelegates(Func<Delegate, bool> condition)
265266
return;
266267
}
267268

268-
newWrappers = RemoveAll(wrappers, CollectionsMarshal.AsSpan(toRemove));
269-
} while (!PublishNewWrappers(newWrappers, wrappers));
270-
271-
// The list of indices is assumed to be sorted in ascending order
272-
static DelegateWrapper[] RemoveAll(DelegateWrapper[] oldCol, ReadOnlySpan<int> toRemove)
273-
{
274-
// Allocate new collection
275-
var newCol = new DelegateWrapper[oldCol.Length - toRemove.Length];
276-
if (newCol.Length == 0)
277-
{
278-
return newCol;
279-
}
280-
281-
// Iterate over collection, skipping elements that should be removed.
282-
int ri = 0;
283-
for (int oi = 0, ni = 0; oi < oldCol.Length; oi++)
269+
newWrappers = wrappers.GetRange(0, wrappers.Count);
270+
foreach (int idx in toRemove)
284271
{
285-
if (ri < toRemove.Length && oi == toRemove[ri])
286-
{
287-
ri++;
288-
continue;
289-
}
290-
291-
newCol[ni] = oldCol[oi];
292-
ni++;
272+
newWrappers.RemoveAt(idx);
293273
}
294-
295-
return newCol;
296-
}
274+
} while (!PublishNewWrappers(newWrappers, wrappers));
297275
}
298276

299277
public object? Invoke(object[] args)
300278
{
301279
Debug.Assert(!Empty);
302280
object? result = null;
303281

304-
DelegateWrapper[] wrappers = _delegateWrappers;
282+
List<DelegateWrapper> wrappers = _delegateWrappers;
305283
foreach (DelegateWrapper wrapper in wrappers)
306284
{
307285
result = wrapper.Invoke(args);
@@ -311,7 +289,7 @@ static DelegateWrapper[] RemoveAll(DelegateWrapper[] oldCol, ReadOnlySpan<int> t
311289
}
312290

313291
// Attempt to update the member wrapper field
314-
private bool PublishNewWrappers(DelegateWrapper[] newWrappers, DelegateWrapper[] currentMaybe)
292+
private bool PublishNewWrappers(List<DelegateWrapper> newWrappers, List<DelegateWrapper> currentMaybe)
315293
{
316294
return Interlocked.CompareExchange(ref _delegateWrappers, newWrappers, currentMaybe) == currentMaybe;
317295
}

0 commit comments

Comments
 (0)