Skip to content

Commit 211e954

Browse files
committed
Added ToInvariantString extension method overloads
Classes implementing the IFormattable interface indicates that they can be converted to a string representation using a specified format. The first overload therefore takes an instance of IFormattable and a second parameter for the format. From .NET 7 and up, .NET features the StringSyntaxAttribute class, that can be used to specify the available format for the "format" parameter, which then can improve the intellisense. Additional extension method overloads for DateTime, DateTimeOffset and TimeSpan are added as well. The extension method overloads are added for all of the current target frameworks. Since StringSyntaxAttribute is only supported from .NET 7 and up, Skybrud.Essentials adds an internal StringSyntaxAttribute class to also support older target frameworks. This should then - in theory - also allow better intellisense for those target frameworks.
1 parent 359b4b9 commit 211e954

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#if !NET7_0_OR_GREATER
2+
3+
// ReSharper disable CheckNamespace
4+
5+
namespace System.Diagnostics.CodeAnalysis;
6+
7+
/// <summary>Specifies the syntax used in a string.</summary>
8+
/// <see>
9+
/// <cref>https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/StringSyntaxAttribute.cs</cref>
10+
/// </see>
11+
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]
12+
internal sealed class StringSyntaxAttribute(string syntax) : Attribute {
13+
14+
/// <summary>Gets the identifier of the syntax used.</summary>
15+
public string Syntax { get; } = syntax;
16+
17+
/// <summary>Optional arguments associated with the specific syntax employed.</summary>
18+
public object?[] Arguments { get; } = [];
19+
20+
/// <summary>The syntax identifier for strings containing composite formats for string formatting.</summary>
21+
public const string CompositeFormat = nameof(CompositeFormat);
22+
23+
/// <summary>The syntax identifier for strings containing date format specifiers.</summary>
24+
public const string DateOnlyFormat = nameof(DateOnlyFormat);
25+
26+
/// <summary>The syntax identifier for strings containing date and time format specifiers.</summary>
27+
public const string DateTimeFormat = nameof(DateTimeFormat);
28+
29+
/// <summary>The syntax identifier for strings containing <see cref="Enum"/> format specifiers.</summary>
30+
public const string EnumFormat = nameof(EnumFormat);
31+
32+
/// <summary>The syntax identifier for strings containing <see cref="Guid"/> format specifiers.</summary>
33+
public const string GuidFormat = nameof(GuidFormat);
34+
35+
/// <summary>The syntax identifier for strings containing JavaScript Object Notation (JSON).</summary>
36+
public const string Json = nameof(Json);
37+
38+
/// <summary>The syntax identifier for strings containing numeric format specifiers.</summary>
39+
public const string NumericFormat = nameof(NumericFormat);
40+
41+
/// <summary>The syntax identifier for strings containing regular expressions.</summary>
42+
public const string Regex = nameof(Regex);
43+
44+
/// <summary>The syntax identifier for strings containing time format specifiers.</summary>
45+
public const string TimeOnlyFormat = nameof(TimeOnlyFormat);
46+
47+
/// <summary>The syntax identifier for strings containing <see cref="TimeSpan"/> format specifiers.</summary>
48+
public const string TimeSpanFormat = nameof(TimeSpanFormat);
49+
50+
/// <summary>The syntax identifier for strings containing URIs.</summary>
51+
public const string Uri = nameof(Uri);
52+
53+
/// <summary>The syntax identifier for strings containing XML.</summary>
54+
public const string Xml = nameof(Xml);
55+
56+
}
57+
58+
#endif

src/Skybrud.Essentials/Strings/Extensions/StringExtensions.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,50 @@ public static void Split(this string? value, char[] separators, [NotNullIfNotNul
507507
return value is null ? null : string.Format(CultureInfo.InvariantCulture, "{0}", value);
508508
}
509509

510+
/// <summary>
511+
/// Returns a culture invariant string representation of the specified <paramref name="value"/> formatted using <paramref name="format"/>.
512+
/// </summary>
513+
/// <param name="value">The value to convert.</param>
514+
/// <param name="format">The format to be used when converting <paramref name="value"/>.</param>
515+
/// <returns>A culture invariant string representation of <paramref name="value"/>.</returns>
516+
[return: NotNullIfNotNull(nameof(value))]
517+
public static string? ToInvariantString(this IFormattable? value, string format) {
518+
return value is null ? null : string.Format(CultureInfo.InvariantCulture, format, value);
519+
}
520+
521+
/// <summary>
522+
/// Returns a culture invariant string representation of the specified <paramref name="value"/> formatted using <paramref name="format"/>.
523+
/// </summary>
524+
/// <param name="value">The <see cref="DateTime"/> value to convert.</param>
525+
/// <param name="format">The format to be used when converting <paramref name="value"/>.</param>
526+
/// <returns>A culture invariant string representation of <paramref name="value"/>.</returns>
527+
[return: NotNullIfNotNull(nameof(value))]
528+
public static string? ToInvariantString(this DateTime? value, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string format) {
529+
return value is null ? null : string.Format(CultureInfo.InvariantCulture, format, value);
530+
}
531+
532+
/// <summary>
533+
/// Returns a culture invariant string representation of the specified <paramref name="value"/> formatted using <paramref name="format"/>.
534+
/// </summary>
535+
/// <param name="value">The <see cref="DateTimeOffset"/> value to convert.</param>
536+
/// <param name="format">The format to be used when converting <paramref name="value"/>.</param>
537+
/// <returns>A culture invariant string representation of <paramref name="value"/>.</returns>
538+
[return: NotNullIfNotNull(nameof(value))]
539+
public static string? ToInvariantString(this DateTimeOffset? value, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string format) {
540+
return value is null ? null : string.Format(CultureInfo.InvariantCulture, format, value);
541+
}
542+
543+
/// <summary>
544+
/// Returns a culture invariant string representation of the specified <paramref name="value"/> formatted using <paramref name="format"/>.
545+
/// </summary>
546+
/// <param name="value">The <see cref="TimeSpan"/> value to convert.</param>
547+
/// <param name="format">The format to be used when converting <paramref name="value"/>.</param>
548+
/// <returns>A culture invariant string representation of <paramref name="value"/>.</returns>
549+
[return: NotNullIfNotNull(nameof(value))]
550+
public static string? ToInvariantString(this TimeSpan? value, [StringSyntax(StringSyntaxAttribute.TimeSpanFormat)] string format) {
551+
return value is null ? null : string.Format(CultureInfo.InvariantCulture, format, value);
552+
}
553+
510554
}
511555

512556
}

0 commit comments

Comments
 (0)