Skip to content

Commit 92ba095

Browse files
Support DateOnly and TimeOnly in Blazor parameter change detection (#55914)
Co-authored-by: Mackinnon Buck <[email protected]>
1 parent e709ffe commit 92ba095

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/Components/Components/src/ChangeDetection.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Collections.Concurrent;
5+
using Microsoft.AspNetCore.Components.HotReload;
6+
47
namespace Microsoft.AspNetCore.Components;
58

69
internal sealed class ChangeDetection
710
{
11+
private static readonly ConcurrentDictionary<Type, bool> _immutableObjectTypesCache = new();
12+
13+
static ChangeDetection()
14+
{
15+
if (HotReloadManager.Default.MetadataUpdateSupported)
16+
{
17+
HotReloadManager.Default.OnDeltaApplied += _immutableObjectTypesCache.Clear;
18+
}
19+
}
20+
821
public static bool MayHaveChanged<T1, T2>(T1 oldValue, T2 newValue)
922
{
1023
var oldIsNotNull = oldValue != null;
@@ -30,17 +43,18 @@ public static bool MayHaveChanged<T1, T2>(T1 oldValue, T2 newValue)
3043
return false;
3144
}
3245

33-
// The contents of this list need to trade off false negatives against computation
34-
// time. So we don't want a huge list of types to check (or would have to move to
35-
// a hashtable lookup, which is differently expensive). It's better not to include
36-
// uncommon types here even if they are known to be immutable.
3746
// This logic assumes that no new System.TypeCode enum entries have been declared since 7.0, or at least that any new ones
3847
// represent immutable types. If System.TypeCode changes, review this logic to ensure it is still correct.
3948
// Supported immutable types : bool, byte, sbyte, short, ushort, int, uint, long, ulong, char, double,
4049
// string, DateTime, decimal, Guid, Enum, EventCallback, EventCallback<>.
4150
// For performance reasons, the following immutable types are not supported: IntPtr, UIntPtr, Type.
4251
private static bool IsKnownImmutableType(Type type)
4352
=> Type.GetTypeCode(type) != TypeCode.Object
44-
|| type == typeof(Guid)
53+
|| _immutableObjectTypesCache.GetOrAdd(type, IsImmutableObjectTypeCore);
54+
55+
private static bool IsImmutableObjectTypeCore(Type type)
56+
=> type == typeof(Guid)
57+
|| type == typeof(DateOnly)
58+
|| type == typeof(TimeOnly)
4559
|| typeof(IEventCallback).IsAssignableFrom(type);
4660
}

src/Components/Components/test/RenderTreeDiffBuilderTest.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,9 @@ public void SkipsUpdatingParametersOnChildComponentsIfAllAreDefinitelyImmutableA
17361736
// Arrange: Populate old and new with equivalent content
17371737
RenderFragment fragmentWillNotChange = builder => throw new NotImplementedException();
17381738
var dateTimeWillNotChange = DateTime.Now;
1739+
var dateOnlyWillNotChange = DateOnly.FromDateTime(dateTimeWillNotChange);
1740+
var timeOnlyWillNotChange = TimeOnly.FromDateTime(dateTimeWillNotChange);
1741+
17391742
foreach (var tree in new[] { oldTree, newTree })
17401743
{
17411744
tree.OpenComponent<CaptureSetParametersComponent>(0);
@@ -1758,6 +1761,8 @@ public void SkipsUpdatingParametersOnChildComponentsIfAllAreDefinitelyImmutableA
17581761
tree.AddComponentParameter(1, "MyEnum", StringComparison.OrdinalIgnoreCase);
17591762
tree.AddComponentParameter(1, "MyEventCallback", EventCallback.Empty);
17601763
tree.AddComponentParameter(1, "MyEventCallbackOfT", EventCallback<int>.Empty);
1764+
tree.AddComponentParameter(1, "MyDateOnly", dateOnlyWillNotChange);
1765+
tree.AddComponentParameter(1, "MyTimeOnly", timeOnlyWillNotChange);
17611766
tree.CloseComponent();
17621767
}
17631768

0 commit comments

Comments
 (0)