Skip to content

Commit 35d93c4

Browse files
CR: Avoid "new T()" in StackObjectPool
1 parent d02d8dc commit 35d93c4

File tree

3 files changed

+13
-11
lines changed

3 files changed

+13
-11
lines changed

src/Components/Components/src/RenderTree/StackObjectPool.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree
99
// balanced as in a stack. It retains up to 'maxPreservedItems' instances in
1010
// memory, then for any further requests it supplies untracked instances.
1111

12-
internal class StackObjectPool<T> where T : class, new()
12+
internal class StackObjectPool<T> where T : class
1313
{
1414
private readonly int _maxPreservedItems;
15+
private readonly Func<T> _instanceFactory;
1516
private readonly T[] _contents;
1617
private int _numSuppliedItems;
1718
private int _numTrackedItems;
1819

19-
public StackObjectPool(int maxPreservedItems)
20+
public StackObjectPool(int maxPreservedItems, Func<T> instanceFactory)
2021
{
2122
_maxPreservedItems = maxPreservedItems;
23+
_instanceFactory = instanceFactory ?? throw new ArgumentNullException(nameof(instanceFactory));
2224
_contents = new T[_maxPreservedItems];
2325
}
2426

@@ -31,7 +33,7 @@ public T Get()
3133
if (_numTrackedItems < _numSuppliedItems)
3234
{
3335
// Need to allocate a new one
34-
var newItem = new T();
36+
var newItem = _instanceFactory();
3537
_contents[_numTrackedItems++] = newItem;
3638
return newItem;
3739
}
@@ -44,7 +46,7 @@ public T Get()
4446
else
4547
{
4648
// Pool is full; return untracked instance
47-
return new T();
49+
return _instanceFactory();
4850
}
4951
}
5052

src/Components/Components/src/Rendering/RenderBatchBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal class RenderBatchBuilder
3131
public Dictionary<string, int> AttributeDiffSet { get; } = new Dictionary<string, int>();
3232

3333
internal StackObjectPool<Dictionary<object, KeyedItemInfo>> KeyedItemInfoDictionaryPool { get; }
34-
= new StackObjectPool<Dictionary<object, KeyedItemInfo>>(maxPreservedItems: 10);
34+
= new StackObjectPool<Dictionary<object, KeyedItemInfo>>(maxPreservedItems: 10, () => new Dictionary<object, KeyedItemInfo>());
3535

3636
public void ClearStateForCurrentBatch()
3737
{

src/Components/Components/test/StackObjectPoolTest.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class StackObjectPoolTest
1313
public void CanGetInstances()
1414
{
1515
// Arrange
16-
var stackObjectPool = new StackObjectPool<object>(10);
16+
var stackObjectPool = new StackObjectPool<object>(10, () => new object());
1717

1818
// Act
1919
var instance1 = stackObjectPool.Get();
@@ -29,7 +29,7 @@ public void CanGetInstances()
2929
public void CanReturnInstances()
3030
{
3131
// Arrange
32-
var stackObjectPool = new StackObjectPool<object>(10);
32+
var stackObjectPool = new StackObjectPool<object>(10, () => new object());
3333
var instance1 = stackObjectPool.Get();
3434
var instance2 = stackObjectPool.Get();
3535

@@ -43,7 +43,7 @@ public void CanReturnInstances()
4343
public void ReusesInstancesInPoolUpToCapacity()
4444
{
4545
// Arrange
46-
var stackObjectPool = new StackObjectPool<object>(10);
46+
var stackObjectPool = new StackObjectPool<object>(10, () => new object());
4747
var instance1 = stackObjectPool.Get();
4848
var instance2 = stackObjectPool.Get();
4949
stackObjectPool.Return(instance2);
@@ -66,7 +66,7 @@ public void ReusesInstancesInPoolUpToCapacity()
6666
public void SuppliesTransientInstancesWhenExceedingCapacity()
6767
{
6868
// Arrange
69-
var stackObjectPool = new StackObjectPool<object>(1);
69+
var stackObjectPool = new StackObjectPool<object>(1, () => new object());
7070

7171
// Act 1: Returns distinct instances beyond capacity
7272
var instance1 = stackObjectPool.Get();
@@ -94,7 +94,7 @@ public void SuppliesTransientInstancesWhenExceedingCapacity()
9494
public void CannotReturnWhenEmpty()
9595
{
9696
// Arrange
97-
var stackObjectPool = new StackObjectPool<object>(10);
97+
var stackObjectPool = new StackObjectPool<object>(10, () => new object());
9898

9999
// Act/Assert
100100
var ex = Assert.Throws<InvalidOperationException>(() =>
@@ -108,7 +108,7 @@ public void CannotReturnWhenEmpty()
108108
public void CannotReturnMismatchingTrackedItem()
109109
{
110110
// Arrange
111-
var stackObjectPool = new StackObjectPool<object>(10);
111+
var stackObjectPool = new StackObjectPool<object>(10, () => new object());
112112
var instance1 = stackObjectPool.Get();
113113
var instance2 = stackObjectPool.Get();
114114

0 commit comments

Comments
 (0)