@@ -47,7 +47,7 @@ namespace NLog.Internal
4747/// in the collection, and in positional order.
4848/// </summary>
4949[ DebuggerDisplay ( "Count = {Count}" ) ]
50- internal sealed class PropertiesDictionary : IDictionary < object , object ? > , IList < MessageTemplateParameter >
50+ internal sealed class PropertiesDictionary : IDictionary < object , object ? >
5151{
5252 private
5353#if! NETFRAMEWORK
@@ -121,7 +121,7 @@ private Dictionary<object, PropertyValue> GetEventProperties(bool prepareForInse
121121return _eventProperties ;
122122}
123123
124- public IList < MessageTemplateParameter > MessageProperties => this ;
124+ public MessageTemplateParameter [ ] MessageProperties => ( _messageProperties is null || _messagePropertiesCount == 0 || _messagePropertiesCount != _messageProperties . Length || _messageProperties [ 0 ] . CaptureType == CaptureType . Unknown ) ? ArrayHelper . Empty < MessageTemplateParameter > ( ) : _messageProperties ;
125125
126126public void ResetMessageProperties ( MessageTemplateParameter [ ] ? newMessageProperties = null , int newMessagePropertiesCount = 0 )
127127{
@@ -134,7 +134,7 @@ public void ResetMessageProperties(MessageTemplateParameter[]? newMessagePropert
134134{
135135eventProperties = _eventProperties = oldMessagePropertiesCount == 0 ?
136136new Dictionary < object , PropertyValue > ( newMessagePropertiesCount , PropertyKeyComparer . Default ) :
137- InitializeEventPropertiesDictionary ( false , oldMessageProperties , oldMessagePropertiesCount , out var _ ) ;
137+ InitializeEventPropertiesDictionary ( newMessagePropertiesCount > oldMessagePropertiesCount , oldMessageProperties , oldMessagePropertiesCount , out var _ ) ;
138138}
139139
140140if ( oldMessageProperties != null && eventProperties . Count > 0 )
@@ -146,13 +146,18 @@ public void ResetMessageProperties(MessageTemplateParameter[]? newMessagePropert
146146{
147147InsertMessagePropertiesIntoEmptyDictionary ( eventProperties , newMessageProperties , newMessagePropertiesCount , out _ ) ;
148148}
149- }
150149
151- _messageProperties = newMessageProperties ;
152- _messagePropertiesCount = newMessagePropertiesCount ;
150+ _messageProperties = newMessageProperties ;
151+ _messagePropertiesCount = newMessagePropertiesCount ;
152+ }
153+ else if ( newMessagePropertiesCount > 0 )
154+ {
155+ _messageProperties = newMessageProperties ;
156+ _messagePropertiesCount = newMessagePropertiesCount ;
157+ }
153158}
154159
155- private static void RemoveOldMessageProperties ( Dictionary < object , PropertyValue > eventProperties , IList < MessageTemplateParameter > oldMessageProperties , int oldMessagePropertiesCount )
160+ private static void RemoveOldMessageProperties ( Dictionary < object , PropertyValue > eventProperties , MessageTemplateParameter [ ] oldMessageProperties , int oldMessagePropertiesCount )
156161{
157162for ( int i = 0 ; i < oldMessagePropertiesCount ; ++ i )
158163{
@@ -165,7 +170,7 @@ private static void RemoveOldMessageProperties(Dictionary<object, PropertyValue>
165170
166171private static Dictionary < object , PropertyValue > InitializeEventPropertiesDictionary ( bool prepareForInsert , MessageTemplateParameter [ ] ? messageProperties , int messagePropertiesCount , out bool resetMessageProperties )
167172{
168- if ( messageProperties != null && messagePropertiesCount > 0 )
173+ if ( messagePropertiesCount > 0 && messageProperties != null )
169174{
170175var dictionaryCapacity = prepareForInsert ? ( messagePropertiesCount + 2 ) : messagePropertiesCount ;
171176var eventProperties = new Dictionary < object , PropertyValue > ( dictionaryCapacity , PropertyKeyComparer . Default ) ;
@@ -195,26 +200,6 @@ private static Dictionary<object, PropertyValue> InitializeEventPropertiesDictio
195200/// <inheritDoc/>
196201public bool IsReadOnly => false ;
197202
198- int ICollection < MessageTemplateParameter > . Count => _messagePropertiesCount ;
199-
200- bool ICollection < MessageTemplateParameter > . IsReadOnly => true ;
201-
202- MessageTemplateParameter IList < MessageTemplateParameter > . this [ int index ]
203- {
204- get
205- {
206- if ( index >= _messagePropertiesCount || index < 0 || _messageProperties is null )
207- throw new ArgumentOutOfRangeException ( nameof ( index ) ) ;
208- return _messageProperties [ index ] ;
209- }
210- set
211- {
212- if ( index >= _messagePropertiesCount || index < 0 || _messageProperties is null )
213- throw new ArgumentOutOfRangeException ( nameof ( index ) ) ;
214- _messageProperties [ index ] = value ;
215- }
216- }
217-
218203/// <inheritDoc/>
219204public object ? this [ object key ]
220205{
@@ -231,16 +216,7 @@ public object? this[object key]
231216{
232217if ( SkipDictionaryAllocation ( ) && key is string propertyName && propertyName . Length > 0 )
233218{
234- var messageProperties = _messageProperties ?? ( _messageProperties = new MessageTemplateParameter [ 3 ] ) ;
235- for ( int i = 0 ; i < _messagePropertiesCount ; ++ i )
236- {
237- if ( messageProperties [ i ] . Name . Equals ( propertyName ) )
238- {
239- messageProperties [ i ] = new MessageTemplateParameter ( messageProperties [ i ] . Name , value , messageProperties [ i ] . Format , messageProperties [ i ] . CaptureType ) ;
240- return ;
241- }
242- }
243- messageProperties [ _messagePropertiesCount ++ ] = new MessageTemplateParameter ( propertyName , value , null , CaptureType . Unknown ) ;
219+ AddOrUpdateMessageProperties ( propertyName , value , true ) ;
244220return ;
245221}
246222
@@ -253,26 +229,13 @@ public void Add(object key, object? value)
253229{
254230if ( SkipDictionaryAllocation ( ) && key is string propertyName && propertyName . Length > 0 )
255231{
256- var messageProperties = _messageProperties ?? ( _messageProperties = new MessageTemplateParameter [ 3 ] ) ;
257- for ( int i = 0 ; i < _messagePropertiesCount ; ++ i )
258- {
259- if ( messageProperties [ i ] . Name . Equals ( propertyName ) )
260- {
261- throw new ArgumentException ( $ "An item with the same key{ propertyName } has already been added.", nameof ( key ) ) ;
262- }
263- }
264- messageProperties [ _messagePropertiesCount ++ ] = new MessageTemplateParameter ( propertyName , value , null , CaptureType . Unknown ) ;
232+ AddOrUpdateMessageProperties ( propertyName , value , false ) ;
265233return ;
266234}
267235
268236GetEventProperties ( true ) [ key ] = new PropertyValue ( value , false ) ;
269237}
270238
271- private bool SkipDictionaryAllocation ( )
272- {
273- return _eventProperties is null && ( _messageProperties is null || _messagePropertiesCount < _messageProperties . Length ) ;
274- }
275-
276239/// <inheritDoc/>
277240public void Add ( KeyValuePair < object , object ? > item )
278241{
@@ -370,18 +333,15 @@ public bool Remove(KeyValuePair<object, object?> item)
370333/// <inheritDoc/>
371334public bool TryGetValue ( object key , out object ? value )
372335{
373- if ( ! IsEmpty )
336+ if ( _eventProperties is null )
374337{
375- if ( _eventProperties is null )
376- {
377- return TryLookupMessagePropertyValue ( key , out value ) ;
378- }
338+ return TryLookupMessagePropertyValue ( key , out value ) ;
339+ }
379340
380- if ( _eventProperties . TryGetValue ( key , out var eventProperty ) )
381- {
382- value = eventProperty . Value ;
383- return true ;
384- }
341+ if ( _eventProperties . TryGetValue ( key , out var eventProperty ) )
342+ {
343+ value = eventProperty . Value ;
344+ return true ;
385345}
386346
387347value = null ;
@@ -431,6 +391,30 @@ private bool TryLookupMessagePropertyValue(object key, out object? propertyValue
431391return false ;
432392}
433393
394+ private void AddOrUpdateMessageProperties ( string propertyName , object ? value , bool allowUpdate )
395+ {
396+ var messageProperties = _messageProperties ?? ( _messageProperties = new MessageTemplateParameter [ 3 ] ) ;
397+ for ( int i = 0 ; i < _messagePropertiesCount ; ++ i )
398+ {
399+ if ( propertyName . Equals ( messageProperties [ i ] . Name ) )
400+ {
401+ if ( ! allowUpdate )
402+ {
403+ throw new ArgumentException ( $ "An item with the same key{ propertyName } has already been added.", nameof ( propertyName ) ) ;
404+ }
405+ messageProperties [ i ] = new MessageTemplateParameter ( propertyName , value , null , CaptureType . Unknown ) ;
406+ return ;
407+ }
408+ }
409+
410+ messageProperties [ _messagePropertiesCount ++ ] = new MessageTemplateParameter ( propertyName , value , null , CaptureType . Unknown ) ;
411+ }
412+
413+ private bool SkipDictionaryAllocation ( )
414+ {
415+ return _eventProperties is null && ( _messageProperties is null || _messagePropertiesCount < _messageProperties . Length ) ;
416+ }
417+
434418/// <summary>
435419/// Check if the message-template-parameters can be used directly without allocating a dictionary
436420/// </summary>
@@ -513,65 +497,6 @@ internal static string GenerateUniquePropertyName<TKey, TValue>(string originalN
513497return newItemName ;
514498}
515499
516- int IList < MessageTemplateParameter > . IndexOf ( MessageTemplateParameter item )
517- {
518- if ( _messageProperties != null && _messagePropertiesCount > 0 )
519- {
520- for ( int i = 0 ; i < _messagePropertiesCount ; ++ i )
521- {
522- if ( _messageProperties [ i ] . Equals ( item ) )
523- return i ;
524- }
525- }
526- return - 1 ;
527- }
528-
529- bool ICollection < MessageTemplateParameter > . Contains ( MessageTemplateParameter item )
530- {
531- return ( ( IList < MessageTemplateParameter > ) this ) . IndexOf ( item ) >= 0 ;
532- }
533-
534- void ICollection < MessageTemplateParameter > . CopyTo ( MessageTemplateParameter [ ] array , int arrayIndex )
535- {
536- if ( _messageProperties != null && _messagePropertiesCount > 0 )
537- {
538- Array . Copy ( _messageProperties , 0 , array , arrayIndex , _messagePropertiesCount ) ;
539- }
540- }
541-
542- void IList < MessageTemplateParameter > . Insert ( int index , MessageTemplateParameter item )
543- {
544- throw new NotSupportedException ( "MessageTemplateParameters array is read-only" ) ;
545- }
546-
547- void IList < MessageTemplateParameter > . RemoveAt ( int index )
548- {
549- throw new NotSupportedException ( "MessageTemplateParameters array is read-only" ) ;
550- }
551-
552- void ICollection < MessageTemplateParameter > . Add ( MessageTemplateParameter item )
553- {
554- throw new NotSupportedException ( "MessageTemplateParameters array is read-only" ) ;
555- }
556-
557- void ICollection < MessageTemplateParameter > . Clear ( )
558- {
559- throw new NotSupportedException ( "MessageTemplateParameters array is read-only" ) ;
560- }
561-
562- bool ICollection < MessageTemplateParameter > . Remove ( MessageTemplateParameter item )
563- {
564- throw new NotSupportedException ( "MessageTemplateParameters array is read-only" ) ;
565- }
566-
567- IEnumerator < MessageTemplateParameter > IEnumerable < MessageTemplateParameter > . GetEnumerator ( )
568- {
569- if ( _messageProperties is null )
570- return System . Linq . Enumerable . Empty < MessageTemplateParameter > ( ) . GetEnumerator ( ) ;
571- else
572- return ( ( IList < MessageTemplateParameter > ) _messageProperties ) . GetEnumerator ( ) ;
573- }
574-
575500public struct PropertyDictionaryEnumerator : IEnumerator < KeyValuePair < object , object ? > >
576501{
577502private readonly PropertiesDictionary _dictionary ;
@@ -699,7 +624,7 @@ public void Dispose()
699624public void Reset ( )
700625{
701626_messagePropertiesIndex = _dictionary . _messagePropertiesCount > 0 ? - 1 : default ( int ? ) ;
702- _eventEnumerator = default ( Dictionary < object , PropertyValue > . Enumerator ) ;
627+ _eventEnumerator = _dictionary . _eventProperties ? . GetEnumerator ( ) ?? default ( Dictionary < object , PropertyValue > . Enumerator ) ;
703628}
704629}
705630