@@ -34,7 +34,7 @@ internal TypeGenerationContext(TypeCache parentCache)
3434 public TypeCache ? ParentCache { get ; }
3535
3636 /// <summary>
37- /// Gets a factory method governing the creation of values when invoking the <see cref="GetOrAdd{TKey} " /> method.
37+ /// Gets a factory method governing the creation of values when invoking the <see cref="GetOrAdd" /> method.
3838 /// </summary>
3939 public ITypeShapeFunc ? ValueBuilder { get ; init ; }
4040
@@ -67,11 +67,10 @@ internal TypeGenerationContext(TypeCache parentCache)
6767 /// <summary>
6868 /// Gets or adds a value keyed on the type represented by <paramref name="typeShape"/>.
6969 /// </summary>
70- /// <typeparam name="TKey">The type key to be looked up.</typeparam>
7170 /// <param name="typeShape">The type shape representing the key type.</param>
7271 /// <param name="state">The state object to be passed to the visitor.</param>
7372 /// <returns>The final computed value.</returns>
74- public object ? GetOrAdd < TKey > ( ITypeShape < TKey > typeShape , object ? state = null )
73+ public object ? GetOrAdd ( ITypeShape typeShape , object ? state = null )
7574 {
7675 Throw . IfNull ( typeShape ) ;
7776 if ( ValueBuilder is null )
@@ -90,28 +89,27 @@ internal TypeGenerationContext(TypeCache parentCache)
9089 }
9190
9291 /// <summary>
93- /// Looks up the value for type <typeparamref name="TKey "/>.
92+ /// Looks up the value for the specified <see cref="ITypeShape "/>.
9493 /// </summary>
95- /// <typeparam name="TKey">The type key to be looked up.</typeparam>
9694 /// <param name="typeShape">The type shape representing the key type.</param>
9795 /// <param name="value">The value returned by the lookup operation.</param>
9896 /// <returns>True if either a completed or delayed value have been returned.</returns>
99- public bool TryGetValue < TKey > ( ITypeShape < TKey > typeShape , [ MaybeNullWhen ( false ) ] out object ? value )
97+ public bool TryGetValue ( ITypeShape typeShape , [ MaybeNullWhen ( false ) ] out object ? value )
10098 {
10199 Throw . IfNull ( typeShape ) ;
102100 ParentCache ? . ValidateProvider ( typeShape . Provider ) ;
103101
104102 // Consult the parent cache first to avoid creating duplicate values.
105- if ( ParentCache ? . TryGetValue ( typeof ( TKey ) , out value ) is true )
103+ if ( ParentCache ? . TryGetValue ( typeShape . Type , out value ) is true )
106104 {
107105 return true ;
108106 }
109107
110108#if NET
111- ref Entry entry = ref CollectionsMarshal . GetValueRefOrNullRef ( _entries , typeof ( TKey ) ) ;
109+ ref Entry entry = ref CollectionsMarshal . GetValueRefOrNullRef ( _entries , typeShape . Type ) ;
112110 bool exists = ! Unsafe . IsNullRef ( ref entry ) ;
113111#else
114- bool exists = _entries . TryGetValue ( typeof ( TKey ) , out Entry entry ) ;
112+ bool exists = _entries . TryGetValue ( typeShape . Type , out Entry entry ) ;
115113#endif
116114
117115 if ( ! exists )
@@ -120,7 +118,7 @@ public bool TryGetValue<TKey>(ITypeShape<TKey> typeShape, [MaybeNullWhen(false)]
120118 {
121119 // First time visiting this type, add an empty entry to the
122120 // dictionary to record that it has been visited and return false.
123- _entries [ typeof ( TKey ) ] = new ( EntryKind . Empty ) ;
121+ _entries [ typeShape . Type ] = new ( EntryKind . Empty ) ;
124122 }
125123
126124 value = default ;
@@ -134,11 +132,11 @@ public bool TryGetValue<TKey>(ITypeShape<TKey> typeShape, [MaybeNullWhen(false)]
134132 DebugExt . Assert ( DelayedValueFactory is not null ) ;
135133
136134 // Create a delayed value and return the uninitialized result.
137- DelayedValue delayedValue = DelayedValueFactory . Create ( typeShape ) ;
135+ DelayedValue delayedValue = ( DelayedValue ) typeShape . Invoke ( UntypedDelayedValueFactoryInvoker . Instance , DelayedValueFactory ) ! ;
138136 value = delayedValue . PotentiallyDelayedResult ;
139137 entry = new ( EntryKind . DelayedValue , delayedValue ) ;
140138#if ! NET
141- _entries [ typeof ( TKey ) ] = entry ;
139+ _entries [ typeShape . Type ] = entry ;
142140#endif
143141 return true ;
144142
@@ -304,4 +302,10 @@ private enum EntryKind
304302 IEnumerable < Type > IReadOnlyDictionary < Type , object ? > . Keys => GetCompletedValues ( ) . Select ( kvp => kvp . Key ) ;
305303 IEnumerable < object ? > IReadOnlyDictionary < Type , object ? > . Values => GetCompletedValues ( ) . Select ( kvp => kvp . Value . Value ) ;
306304 private IEnumerable < KeyValuePair < Type , Entry > > GetCompletedValues ( ) => _entries . Where ( kvp => kvp . Value . Kind is EntryKind . CompletedValue ) ;
305+
306+ private sealed class UntypedDelayedValueFactoryInvoker : ITypeShapeFunc
307+ {
308+ public static readonly UntypedDelayedValueFactoryInvoker Instance = new ( ) ;
309+ object ? ITypeShapeFunc . Invoke < T > ( ITypeShape < T > typeShape , object ? state ) => ( ( IDelayedValueFactory ) state ! ) . Create ( typeShape ) ;
310+ }
307311}
0 commit comments