diff --git a/src/Avalonia.Base/Utilities/AvaloniaPropertyValueStore.cs b/src/Avalonia.Base/Utilities/AvaloniaPropertyValueStore.cs
index 0238446892..6e52b6770a 100644
--- a/src/Avalonia.Base/Utilities/AvaloniaPropertyValueStore.cs
+++ b/src/Avalonia.Base/Utilities/AvaloniaPropertyValueStore.cs
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+#nullable enable
namespace Avalonia.Utilities
{
@@ -9,12 +12,14 @@ namespace Avalonia.Utilities
/// Stored value type.
internal sealed class AvaloniaPropertyValueStore
{
+ // The last item in the list is always int.MaxValue.
+ private static readonly Entry[] s_emptyEntries = { new Entry { PropertyId = int.MaxValue, Value = default! } };
+
private Entry[] _entries;
public AvaloniaPropertyValueStore()
{
- // The last item in the list is always int.MaxValue
- _entries = new[] { new Entry { PropertyId = int.MaxValue, Value = default } };
+ _entries = s_emptyEntries;
}
private (int, bool) TryFindEntry(int propertyId)
@@ -86,7 +91,7 @@ namespace Avalonia.Utilities
return (0, false);
}
- public bool TryGetValue(AvaloniaProperty property, out TValue value)
+ public bool TryGetValue(AvaloniaProperty property, [MaybeNull] out TValue value)
{
(int index, bool found) = TryFindEntry(property.Id);
if (!found)
@@ -132,7 +137,18 @@ namespace Avalonia.Utilities
if (found)
{
- Entry[] entries = new Entry[_entries.Length - 1];
+ var newLength = _entries.Length - 1;
+
+ // Special case - one element left means that value store is empty so we can just reuse our "empty" array.
+ if (newLength == 1)
+ {
+ _entries = s_emptyEntries;
+
+ return;
+ }
+
+ var entries = new Entry[newLength];
+
int ix = 0;
for (int i = 0; i < _entries.Length; ++i)
diff --git a/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs b/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
index 7170f6d7d4..3493dd0f53 100644
--- a/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
+++ b/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs
@@ -17,7 +17,8 @@ namespace Avalonia.Benchmarks.Layout
_app = UnitTestApplication.Start(
TestServices.StyledWindow.With(
renderInterface: new NullRenderingPlatform(),
- threadingInterface: new NullThreadingPlatform()));
+ threadingInterface: new NullThreadingPlatform(),
+ standardCursorFactory: new NullCursorFactory()));
_root = new TestRoot(true, null)
{
diff --git a/tests/Avalonia.Benchmarks/NullCursorFactory.cs b/tests/Avalonia.Benchmarks/NullCursorFactory.cs
new file mode 100644
index 0000000000..012adce0f2
--- /dev/null
+++ b/tests/Avalonia.Benchmarks/NullCursorFactory.cs
@@ -0,0 +1,14 @@
+using System;
+using Avalonia.Input;
+using Avalonia.Platform;
+
+namespace Avalonia.Benchmarks
+{
+ internal class NullCursorFactory : IStandardCursorFactory
+ {
+ public IPlatformHandle GetCursor(StandardCursorType cursorType)
+ {
+ return new PlatformHandle(IntPtr.Zero, "null");
+ }
+ }
+}