@@ -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 => _messagePropertiesCount > 0 && _messageProperties ? . Length == _messagePropertiesCount ? _messageProperties : ArrayHelper . Empty < MessageTemplateParameter > ( ) ;
125125
126126public void ResetMessageProperties ( MessageTemplateParameter [ ] ? newMessageProperties = null , int newMessagePropertiesCount = 0 )
127127{
@@ -152,7 +152,7 @@ public void ResetMessageProperties(MessageTemplateParameter[]? newMessagePropert
152152_messagePropertiesCount = newMessagePropertiesCount ;
153153}
154154
155- private static void RemoveOldMessageProperties ( Dictionary < object , PropertyValue > eventProperties , IList < MessageTemplateParameter > oldMessageProperties , int oldMessagePropertiesCount )
155+ private static void RemoveOldMessageProperties ( Dictionary < object , PropertyValue > eventProperties , MessageTemplateParameter [ ] oldMessageProperties , int oldMessagePropertiesCount )
156156{
157157for ( int i = 0 ; i < oldMessagePropertiesCount ; ++ i )
158158{
@@ -165,7 +165,7 @@ private static void RemoveOldMessageProperties(Dictionary<object, PropertyValue>
165165
166166private static Dictionary < object , PropertyValue > InitializeEventPropertiesDictionary ( bool prepareForInsert , MessageTemplateParameter [ ] ? messageProperties , int messagePropertiesCount , out bool resetMessageProperties )
167167{
168- if ( messageProperties != null && messagePropertiesCount > 0 )
168+ if ( messagePropertiesCount > 0 && messageProperties != null )
169169{
170170var dictionaryCapacity = prepareForInsert ? ( messagePropertiesCount + 2 ) : messagePropertiesCount ;
171171var eventProperties = new Dictionary < object , PropertyValue > ( dictionaryCapacity , PropertyKeyComparer . Default ) ;
@@ -195,26 +195,6 @@ private static Dictionary<object, PropertyValue> InitializeEventPropertiesDictio
195195/// <inheritDoc/>
196196public bool IsReadOnly => false ;
197197
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-
218198/// <inheritDoc/>
219199public object ? this [ object key ]
220200{
@@ -231,16 +211,7 @@ public object? this[object key]
231211{
232212if ( SkipDictionaryAllocation ( ) && key is string propertyName && propertyName . Length > 0 )
233213{
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 ) ;
214+ AddOrUpdateMessageProperties ( propertyName , value , true ) ;
244215return ;
245216}
246217
@@ -253,26 +224,13 @@ public void Add(object key, object? value)
253224{
254225if ( SkipDictionaryAllocation ( ) && key is string propertyName && propertyName . Length > 0 )
255226{
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 ) ;
227+ AddOrUpdateMessageProperties ( propertyName , value , false ) ;
265228return ;
266229}
267230
268231GetEventProperties ( true ) [ key ] = new PropertyValue ( value , false ) ;
269232}
270233
271- private bool SkipDictionaryAllocation ( )
272- {
273- return _eventProperties is null && ( _messageProperties is null || _messagePropertiesCount < _messageProperties . Length ) ;
274- }
275-
276234/// <inheritDoc/>
277235public void Add ( KeyValuePair < object , object ? > item )
278236{
@@ -431,6 +389,30 @@ private bool TryLookupMessagePropertyValue(object key, out object? propertyValue
431389return false ;
432390}
433391
392+ private void AddOrUpdateMessageProperties ( string propertyName , object ? value , bool allowUpdate )
393+ {
394+ var messageProperties = _messageProperties ?? ( _messageProperties = new MessageTemplateParameter [ 3 ] ) ;
395+ for ( int i = 0 ; i < _messagePropertiesCount ; ++ i )
396+ {
397+ if ( propertyName . Equals ( messageProperties [ i ] . Name ) )
398+ {
399+ if ( ! allowUpdate )
400+ {
401+ throw new ArgumentException ( $ "An item with the same key{ propertyName } has already been added.", nameof ( propertyName ) ) ;
402+ }
403+ messageProperties [ i ] = new MessageTemplateParameter ( propertyName , value , null , CaptureType . Unknown ) ;
404+ return ;
405+ }
406+ }
407+
408+ messageProperties [ _messagePropertiesCount ++ ] = new MessageTemplateParameter ( propertyName , value , null , CaptureType . Unknown ) ;
409+ }
410+
411+ private bool SkipDictionaryAllocation ( )
412+ {
413+ return _eventProperties is null && ( _messageProperties is null || _messagePropertiesCount < _messageProperties . Length ) ;
414+ }
415+
434416/// <summary>
435417/// Check if the message-template-parameters can be used directly without allocating a dictionary
436418/// </summary>
@@ -513,65 +495,6 @@ internal static string GenerateUniquePropertyName<TKey, TValue>(string originalN
513495return newItemName ;
514496}
515497
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-
575498public struct PropertyDictionaryEnumerator : IEnumerator < KeyValuePair < object , object ? > >
576499{
577500private readonly PropertiesDictionary _dictionary ;