@@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Http
19
19
/// <summary>
20
20
/// Represents the empty path. This field is read-only.
21
21
/// </summary>
22
- public static readonly PathString Empty = new PathString ( string . Empty ) ;
22
+ public static readonly PathString Empty = new ( string . Empty ) ;
23
23
24
24
/// <summary>
25
25
/// Initialize the path string with a given value. This value must be in unescaped format. Use
@@ -103,11 +103,7 @@ private static string ToEscapedUriComponent(string value, int i)
103
103
if ( requiresEscaping )
104
104
{
105
105
// the current segment requires escape
106
- if ( buffer == null )
107
- {
108
- buffer = new StringBuilder ( value . Length * 3 ) ;
109
- }
110
-
106
+ buffer ??= new StringBuilder ( value . Length * 3 ) ;
111
107
buffer . Append ( Uri . EscapeDataString ( value . Substring ( start , count ) ) ) ;
112
108
113
109
requiresEscaping = false ;
@@ -131,11 +127,7 @@ private static string ToEscapedUriComponent(string value, int i)
131
127
if ( ! requiresEscaping )
132
128
{
133
129
// the current segment doesn't require escape
134
- if ( buffer == null )
135
- {
136
- buffer = new StringBuilder ( value . Length * 3 ) ;
137
- }
138
-
130
+ buffer ??= new StringBuilder ( value . Length * 3 ) ;
139
131
buffer . Append ( value , start , count ) ;
140
132
141
133
requiresEscaping = true ;
@@ -156,10 +148,7 @@ private static string ToEscapedUriComponent(string value, int i)
156
148
{
157
149
if ( count > 0 )
158
150
{
159
- if ( buffer == null )
160
- {
161
- buffer = new StringBuilder ( value . Length * 3 ) ;
162
- }
151
+ buffer ??= new StringBuilder ( value . Length * 3 ) ;
163
152
164
153
if ( requiresEscaping )
165
154
{
@@ -259,7 +248,7 @@ public bool StartsWithSegments(PathString other, StringComparison comparisonType
259
248
{
260
249
if ( value1 . Length == value2 . Length || value1 [ value2 . Length ] == '/' )
261
250
{
262
- remaining = new PathString ( value1 . Substring ( value2 . Length ) ) ;
251
+ remaining = new PathString ( value1 [ value2 . Length .. ] ) ;
263
252
return true ;
264
253
}
265
254
}
@@ -298,7 +287,7 @@ public bool StartsWithSegments(PathString other, StringComparison comparisonType
298
287
if ( value1 . Length == value2 . Length || value1 [ value2 . Length ] == '/' )
299
288
{
300
289
matched = new PathString ( value1 . Substring ( 0 , value2 . Length ) ) ;
301
- remaining = new PathString ( value1 . Substring ( value2 . Length ) ) ;
290
+ remaining = new PathString ( value1 [ value2 . Length .. ] ) ;
302
291
return true ;
303
292
}
304
293
}
@@ -315,11 +304,12 @@ public PathString Add(PathString other)
315
304
{
316
305
if ( HasValue &&
317
306
other . HasValue &&
318
- Value ! [ Value . Length - 1 ] == '/' )
307
+ Value [ ^ 1 ] == '/' )
319
308
{
320
309
// If the path string has a trailing slash and the other string has a leading slash, we need
321
310
// to trim one of them.
322
- return new PathString ( Value + other . Value ! . Substring ( 1 ) ) ;
311
+ var combined = string . Concat ( Value . AsSpan ( ) , other . Value . AsSpan ( 1 ) ) ;
312
+ return new PathString ( combined ) ;
323
313
}
324
314
325
315
return new PathString ( Value + other . Value ) ;
@@ -366,11 +356,11 @@ public bool Equals(PathString other, StringComparison comparisonType)
366
356
/// <returns>True if both PathString values are equal</returns>
367
357
public override bool Equals ( object ? obj )
368
358
{
369
- if ( ReferenceEquals ( null , obj ) )
359
+ if ( obj is null )
370
360
{
371
361
return ! HasValue ;
372
362
}
373
- return obj is PathString && Equals ( ( PathString ) obj ) ;
363
+ return obj is PathString pathString && Equals ( pathString ) ;
374
364
}
375
365
376
366
/// <summary>
@@ -471,18 +461,16 @@ internal static PathString ConvertFromString(string? s)
471
461
internal sealed class PathStringConverter : TypeConverter
472
462
{
473
463
public override bool CanConvertFrom ( ITypeDescriptorContext context , Type sourceType )
474
- => sourceType == typeof ( string )
475
- ? true
476
- : base . CanConvertFrom ( context , sourceType ) ;
464
+ => sourceType == typeof ( string ) || base . CanConvertFrom ( context , sourceType ) ;
477
465
478
466
public override object ConvertFrom ( ITypeDescriptorContext context , CultureInfo culture , object value )
479
- => value is string
480
- ? PathString . ConvertFromString ( ( string ) value )
467
+ => value is string @string
468
+ ? PathString . ConvertFromString ( @ string)
481
469
: base . ConvertFrom ( context , culture , value ) ;
482
470
483
471
public override object ConvertTo ( ITypeDescriptorContext context ,
484
472
CultureInfo culture , object value , Type destinationType )
485
- => destinationType == typeof ( string )
473
+ => destinationType == typeof ( string )
486
474
? value . ToString ( ) ?? string . Empty
487
475
: base . ConvertTo ( context , culture , value , destinationType ) ;
488
476
}
0 commit comments