@@ -377,23 +377,26 @@ private string GetUrlEncodedValue(string placeholder, string value, string url)
377377 return null ;
378378 }
379379
380+ // Pre-compute all replacement values
380381 string relativeFullPath = GetRelativeFullPath ( fullPath , watchPath ) ;
381382 string ? relativePath = GetRelativePath ( fullPath , watchPath ) ;
382383 string ? fileName = TEFS . File . GetName ( fullPath , true ) ;
383384 string ? fileNameWithoutExtension = TEFS . File . GetName ( fullPath , false ) ;
384385 string ? extension = TEFS . File . GetExtension ( fullPath ) ;
385386
386- string replacedValue = value ;
387- replacedValue = replacedValue . Replace ( PLACEHOLDERWATCHPATH , watchPath , StringComparison . OrdinalIgnoreCase ) ;
388- replacedValue = replacedValue . Replace ( PLACEHOLDEREXACTPATH , fullPath , StringComparison . OrdinalIgnoreCase ) ;
389- replacedValue = replacedValue . Replace ( PLACEHOLDERFULLPATH , relativeFullPath , StringComparison . OrdinalIgnoreCase ) ;
390- replacedValue = replacedValue . Replace ( PLACEHOLDERPATH , relativePath , StringComparison . OrdinalIgnoreCase ) ;
391- replacedValue = replacedValue . Replace ( PLACEHOLDERFILENAME , fileName , StringComparison . OrdinalIgnoreCase ) ;
392- replacedValue = replacedValue . Replace ( PLACEHOLDERFILE , fileNameWithoutExtension , StringComparison . OrdinalIgnoreCase ) ;
393- replacedValue = replacedValue . Replace ( PLACEHOLDEREXTENSION , extension , StringComparison . OrdinalIgnoreCase ) ;
394-
395- // If the changes include an old path, such as when a file/folder
396- // is renamed, then replace those placeholders
387+ // Build replacement dictionary to avoid chained string allocations
388+ var replacements = new Dictionary < string , string ? > ( StringComparer . OrdinalIgnoreCase )
389+ {
390+ [ PLACEHOLDERWATCHPATH ] = watchPath ,
391+ [ PLACEHOLDEREXACTPATH ] = fullPath ,
392+ [ PLACEHOLDERFULLPATH ] = relativeFullPath ,
393+ [ PLACEHOLDERPATH ] = relativePath ,
394+ [ PLACEHOLDERFILENAME ] = fileName ,
395+ [ PLACEHOLDERFILE ] = fileNameWithoutExtension ,
396+ [ PLACEHOLDEREXTENSION ] = extension
397+ } ;
398+
399+ // If the changes include an old path, add those replacements
397400 if ( ! string . IsNullOrWhiteSpace ( oldPath ) )
398401 {
399402 string oldRelativeFullPath = GetRelativeFullPath ( oldPath , watchPath ) ;
@@ -402,12 +405,22 @@ private string GetUrlEncodedValue(string placeholder, string value, string url)
402405 string ? oldFileNameWithoutExtension = TEFS . File . GetName ( oldPath , false ) ;
403406 string ? oldExtension = TEFS . File . GetExtension ( oldPath ) ;
404407
405- replacedValue = replacedValue . Replace ( PLACEHOLDEROLDEXACTPATH , oldPath , StringComparison . OrdinalIgnoreCase ) ;
406- replacedValue = replacedValue . Replace ( PLACEHOLDEROLDFULLPATH , oldRelativeFullPath , StringComparison . OrdinalIgnoreCase ) ;
407- replacedValue = replacedValue . Replace ( PLACEHOLDEROLDPATH , oldRelativePath , StringComparison . OrdinalIgnoreCase ) ;
408- replacedValue = replacedValue . Replace ( PLACEHOLDEROLDFILENAME , oldFileName , StringComparison . OrdinalIgnoreCase ) ;
409- replacedValue = replacedValue . Replace ( PLACEHOLDEROLDFILE , oldFileNameWithoutExtension , StringComparison . OrdinalIgnoreCase ) ;
410- replacedValue = replacedValue . Replace ( PLACEHOLDEROLDEXTENSION , oldExtension , StringComparison . OrdinalIgnoreCase ) ;
408+ replacements [ PLACEHOLDEROLDEXACTPATH ] = oldPath ;
409+ replacements [ PLACEHOLDEROLDFULLPATH ] = oldRelativeFullPath ;
410+ replacements [ PLACEHOLDEROLDPATH ] = oldRelativePath ;
411+ replacements [ PLACEHOLDEROLDFILENAME ] = oldFileName ;
412+ replacements [ PLACEHOLDEROLDFILE ] = oldFileNameWithoutExtension ;
413+ replacements [ PLACEHOLDEROLDEXTENSION ] = oldExtension ;
414+ }
415+
416+ // Perform all replacements efficiently
417+ string replacedValue = value ;
418+ foreach ( var kvp in replacements )
419+ {
420+ if ( kvp . Value != null )
421+ {
422+ replacedValue = replacedValue . Replace ( kvp . Key , kvp . Value , StringComparison . OrdinalIgnoreCase ) ;
423+ }
411424 }
412425
413426 return replacedValue ;
@@ -445,12 +458,12 @@ private string GetUrlEncodedValue(string placeholder, string value, string url)
445458 {
446459 // Loop through each of the matches so the placeholder can
447460 // be replaced with the actual date values
448- foreach ( Match match in matches . Cast < Match > ( ) )
461+ // Use indexed access instead of Cast<Match>() to avoid LINQ allocation
462+ for ( int i = 0 ; i < matches . Count ; i ++ )
449463 {
464+ Match match = matches [ i ] ;
450465
451- // Store the date type (createddate, modifieddate,
452- // or currentdate) and change it to lowercase so it can
453- // be easily compared later
466+ // Store the date type and convert to lowercase once
454467 string type = match . Groups [ "type" ] . Value . ToLower ( CultureInfo . CurrentCulture ) ;
455468 // Store the specified date format
456469 string format = match . Groups [ "format" ] . Value ;
0 commit comments