diff --git a/src/.editorconfig b/src/.editorconfig index a604297..95cae3f 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -12,6 +12,7 @@ indent_style = space charset = utf-8-bom end_of_line = crlf indent_size = 4 +tab_width = 4 insert_final_newline = true trim_trailing_whitespace = true @@ -51,6 +52,17 @@ dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_readonly_field = true:warning dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_code_quality_unused_parameters = all:error + +# Experimental +dotnet_style_allow_multiple_blank_lines_experimental = false:error +dotnet_style_allow_statement_immediately_after_block_experimental = false:error # -- .NET Naming Conventions ---------------------------- # @@ -72,26 +84,26 @@ dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter dotnet_naming_style.parameter_style.capitalization = camel_case dotnet_naming_rule.parameters_are_camel_case.severity = warning dotnet_naming_rule.parameters_are_camel_case.symbols = parameter_symbol -dotnet_naming_rule.parameters_are_camel_case.style = parameter_style +dotnet_naming_rule.parameters_are_camel_case.style = private_field_style dotnet_naming_symbols.non_interface_type_symbol.applicable_kinds = class,struct,enum,delegate dotnet_naming_style.non_interface_type_style.capitalization = pascal_case dotnet_naming_rule.non_interface_types_are_pascal_case.severity = warning dotnet_naming_rule.non_interface_types_are_pascal_case.symbols = non_interface_type_symbol -dotnet_naming_rule.non_interface_types_are_pascal_case.style = non_interface_type_style +dotnet_naming_rule.non_interface_types_are_pascal_case.style = non_private_field_style dotnet_naming_symbols.interface_type_symbol.applicable_kinds = interface dotnet_naming_style.interface_type_style.capitalization = pascal_case dotnet_naming_style.interface_type_style.required_prefix = I -dotnet_naming_rule.interface_types_must_be_prefixed_with_I.severity = warning +dotnet_naming_rule.interface_types_must_be_prefixed_with_i.severity = warning dotnet_naming_rule.interface_types_must_be_prefixed_with_I.symbols = interface_type_symbol -dotnet_naming_rule.interface_types_must_be_prefixed_with_I.style = interface_type_style +dotnet_naming_rule.interface_types_must_be_prefixed_with_i.style = interface_type_style dotnet_naming_symbols.member_symbol.applicable_kinds = method,property,event dotnet_naming_style.member_style.capitalization = pascal_case dotnet_naming_rule.members_are_pascal_case.severity = warning dotnet_naming_rule.members_are_pascal_case.symbols = member_symbol -dotnet_naming_rule.members_are_pascal_case.style = member_style +dotnet_naming_rule.members_are_pascal_case.style = non_private_field_style # -- C# Files ------------------------------------------- # @@ -167,3 +179,36 @@ csharp_space_between_method_declaration_name_and_open_parenthesis = false csharp_space_between_method_declaration_parameter_list_parentheses = false csharp_space_between_parentheses = none csharp_space_between_square_brackets = false + +# General Styling +csharp_using_directive_placement = outside_namespace:error +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_static_local_function = true:suggestion +csharp_style_prefer_switch_expression = true:suggestion +csharp_style_prefer_pattern_matching = true:suggestion +csharp_style_prefer_not_pattern = true:error +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_namespace_declarations = file_scoped:suggestion +csharp_style_prefer_method_group_conversion = true:suggestion +csharp_style_prefer_top_level_statements = false:silent +csharp_style_prefer_primary_constructors = false:silent +csharp_style_expression_bodied_lambdas = true:suggestion +csharp_style_expression_bodied_local_functions = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion +csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion + +# Experimental +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent diff --git a/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeOffsetProvider.cs b/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeOffsetProvider.cs index cba7558..b5866d4 100644 --- a/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeOffsetProvider.cs +++ b/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeOffsetProvider.cs @@ -2,8 +2,18 @@ namespace JK.Common.DateTimeProviders; +/// +/// Abstraction to disconnect from the system clock. +/// public interface IDateTimeOffsetProvider { + /// + /// Returns a representing the current date and time. + /// DateTimeOffset Now { get; } + + /// + /// Returns a representing the current UTC date and time. + /// DateTimeOffset UtcNow { get; } } diff --git a/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeProvider.cs b/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeProvider.cs index 21756e7..17225f2 100644 --- a/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeProvider.cs +++ b/src/JK.Common.Abstractions/DateTimeProviders/IDateTimeProvider.cs @@ -2,9 +2,25 @@ namespace JK.Common.DateTimeProviders; +/// +/// Abstraction to disconnect from the system clock. +/// public interface IDateTimeProvider { + /// + /// Returns a representing the current date and time. + /// DateTime Now { get; } + + /// + /// Returns a DateTime representing the current date. The date part + /// of the returned value is the current date, and the time-of-day part of + /// the returned value is zero (midnight). + /// DateTime Today { get; } + + /// + /// Returns a representing the current UTC date and time. + /// DateTime UtcNow { get; } } diff --git a/src/JK.Common.FluentValidation/Validators/AlphabeticalValidator.cs b/src/JK.Common.FluentValidation/Validators/AlphabeticalValidator.cs index 566fb64..83d6df2 100644 --- a/src/JK.Common.FluentValidation/Validators/AlphabeticalValidator.cs +++ b/src/JK.Common.FluentValidation/Validators/AlphabeticalValidator.cs @@ -2,6 +2,9 @@ namespace JK.Common.FluentValidation.Validators; +/// +/// Validator to determine whether or not a string property contains only alphabetical characters. +/// public class AlphabeticalValidator : StringValidatorBase { /// diff --git a/src/JK.Common.FluentValidation/Validators/NullValidator.cs b/src/JK.Common.FluentValidation/Validators/NullValidator.cs index 60796da..1875467 100644 --- a/src/JK.Common.FluentValidation/Validators/NullValidator.cs +++ b/src/JK.Common.FluentValidation/Validators/NullValidator.cs @@ -2,6 +2,10 @@ namespace JK.Common.FluentValidation.Validators; +/// +/// Null object pattern AbstractValidator implementation. +/// +/// public class NullValidator : AbstractValidator { } diff --git a/src/JK.Common.FluentValidation/Validators/SocialSecurityNumberValidator.cs b/src/JK.Common.FluentValidation/Validators/SocialSecurityNumberValidator.cs index b454912..ce13e28 100644 --- a/src/JK.Common.FluentValidation/Validators/SocialSecurityNumberValidator.cs +++ b/src/JK.Common.FluentValidation/Validators/SocialSecurityNumberValidator.cs @@ -2,6 +2,9 @@ namespace JK.Common.FluentValidation.Validators; +/// +/// Validator to determine whether or not a string property is a valid United States social security number. +/// public class SocialSecurityNumberValidator : StringValidatorBase { /// diff --git a/src/JK.Common.FluentValidation/Validators/StringValidatorBase.cs b/src/JK.Common.FluentValidation/Validators/StringValidatorBase.cs index eef0fcd..1d6eea8 100644 --- a/src/JK.Common.FluentValidation/Validators/StringValidatorBase.cs +++ b/src/JK.Common.FluentValidation/Validators/StringValidatorBase.cs @@ -3,6 +3,9 @@ namespace JK.Common.FluentValidation.Validators; +/// +/// String property abstract validator. +/// public abstract class StringValidatorBase : PropertyValidator { /// Determine if the given string is valid. diff --git a/src/JK.Common.FluentValidation/Validators/UnitedStatesPhoneNumberValidator.cs b/src/JK.Common.FluentValidation/Validators/UnitedStatesPhoneNumberValidator.cs index 80a5f0b..53cd419 100644 --- a/src/JK.Common.FluentValidation/Validators/UnitedStatesPhoneNumberValidator.cs +++ b/src/JK.Common.FluentValidation/Validators/UnitedStatesPhoneNumberValidator.cs @@ -2,6 +2,9 @@ namespace JK.Common.FluentValidation.Validators; +/// +/// Validator to determine whether or not a string property is a valid United States phone number. +/// public class UnitedStatesPhoneNumberValidator : StringValidatorBase { /// diff --git a/src/JK.Common.Tests/Extensions/TypeExtensionsTests.cs b/src/JK.Common.Tests/Extensions/TypeExtensionsTests.cs index 1027019..636ae58 100644 --- a/src/JK.Common.Tests/Extensions/TypeExtensionsTests.cs +++ b/src/JK.Common.Tests/Extensions/TypeExtensionsTests.cs @@ -27,27 +27,6 @@ public void DoesImplement_WithoutInterface_False() Assert.False(actual); } - #endregion - - #region IsNullable - - [Theory] - [MemberData(nameof(IsNullable_Data))] - public void IsNullable_Tests(Type type, bool expected) - { - var actual = type.IsNullable(); - Assert.Equal(expected, actual); - } - - public static IEnumerable IsNullable_Data() - => new List - { - new object[] { typeof(int), false }, - new object[] { typeof(int?), true } - }; - - #endregion - private interface IInterface { } @@ -60,4 +39,25 @@ private class TestWithoutInterface private class NotAnInterface { } + + #endregion + + #region IsNullableT + + [Theory] + [MemberData(nameof(IsNullableT_Data))] + public void IsNullable_Tests(Type type, bool expected) + { + var actual = type.IsNullableT(); + Assert.Equal(expected, actual); + } + + public static IEnumerable IsNullableT_Data() + => + [ + [typeof(int), false], + [typeof(int?), true] + ]; + + #endregion } diff --git a/src/JK.Common.Tests/TypeHelpers/TypeHelperTests.cs b/src/JK.Common.Tests/TypeHelpers/TypeHelperTests.cs index 2a83842..d9dc754 100644 --- a/src/JK.Common.Tests/TypeHelpers/TypeHelperTests.cs +++ b/src/JK.Common.Tests/TypeHelpers/TypeHelperTests.cs @@ -1,37 +1,40 @@ -using System.Collections.Generic; -using JK.Common.TypeHelpers; +using JK.Common.TypeHelpers; namespace JK.Common.Tests.TypeHelpers; public class TypeHelperTests { [Theory] - [MemberData(nameof(IsNullable_Data))] - public void IsNullable_Tests(Type type, bool expected) + [MemberData(nameof(IsNullableT_Data))] + public void IsNullableT_Theories(Type type, bool expected) { - var actual = TypeHelper.IsNullable(type); + var actual = TypeHelper.IsNullableT(type); Assert.Equal(expected, actual); } - [Fact] - public void IsNullableT_False() - { - var actual = TypeHelper.IsNullable(); - Assert.False(actual); - } + public static TheoryData IsNullableT_Data() + => new() + { + { typeof(int), false }, + { typeof(int?), true }, + { typeof(string), false }, + { typeof(ComplexObject), false }, + }; - [Fact] - public void IsNullableT_True() + [Theory] + [MemberData(nameof(IsNullable_Data))] + public void IsNullable_Theories(Type type, bool expected) { - var actual = TypeHelper.IsNullable(); - Assert.True(actual); + var actual = TypeHelper.IsNullable(type); + Assert.Equal(expected, actual); } - public static IEnumerable IsNullable_Data() - => new List + public static TheoryData IsNullable_Data() + => new() { - new object[] { typeof(int), false }, - new object[] { typeof(int?), true }, - new object[] { typeof(ComplexObject), false } + { typeof(int), false }, + { typeof(int?), true }, + { typeof(string), true }, + { typeof(ComplexObject), true } }; } diff --git a/src/JK.Common/CHANGELOG.md b/src/JK.Common/CHANGELOG.md index cffd08e..eb0a08c 100644 --- a/src/JK.Common/CHANGELOG.md +++ b/src/JK.Common/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Unless otherwise noted, all changes made by [@jeremyknight-me](https://github.com/jeremyknight-me). +## Unreleased + +## Added + +- `IsNullable` helper method in `TypeHelper` + +## Changed + +- `IsNullable` to `IsNullableT` int `TypeHelper`. + ## 5.2.0 ### Added diff --git a/src/JK.Common/Converters/BooleanConverter.cs b/src/JK.Common/Converters/BooleanConverter.cs index 20dacd0..cf53c66 100644 --- a/src/JK.Common/Converters/BooleanConverter.cs +++ b/src/JK.Common/Converters/BooleanConverter.cs @@ -14,9 +14,9 @@ public sealed class BooleanConverter public BooleanConverter() { - this.trueItems = new object[] { "TRUE", "True", "true", "Y", "y", "YES", "Yes", "yes", 1, "1" }; - this.falseItems = new object[] { "FALSE", "False", "false", "N", "n", "NO", "No", "no", 0, "0" }; - this.nullItems = new object[] { null, "", string.Empty }; + this.trueItems = ["TRUE", "True", "true", "Y", "y", "YES", "Yes", "yes", 1, "1"]; + this.falseItems = ["FALSE", "False", "false", "N", "n", "NO", "No", "no", 0, "0"]; + this.nullItems = [null, "", string.Empty]; } public bool Convert(object value) diff --git a/src/JK.Common/DateTimeProviders/DefaultDateTimeOffsetProvider.cs b/src/JK.Common/DateTimeProviders/DefaultDateTimeOffsetProvider.cs index 94d3577..4f4fd15 100644 --- a/src/JK.Common/DateTimeProviders/DefaultDateTimeOffsetProvider.cs +++ b/src/JK.Common/DateTimeProviders/DefaultDateTimeOffsetProvider.cs @@ -2,8 +2,12 @@ namespace JK.Common.DateTimeProviders; +/// public sealed class DefaultDateTimeOffsetProvider : IDateTimeOffsetProvider { + /// public DateTimeOffset Now => DateTimeOffset.Now; + + /// public DateTimeOffset UtcNow => DateTimeOffset.UtcNow; } diff --git a/src/JK.Common/DateTimeProviders/DefaultDateTimeProvider.cs b/src/JK.Common/DateTimeProviders/DefaultDateTimeProvider.cs index d1e4766..578d2db 100644 --- a/src/JK.Common/DateTimeProviders/DefaultDateTimeProvider.cs +++ b/src/JK.Common/DateTimeProviders/DefaultDateTimeProvider.cs @@ -2,9 +2,15 @@ namespace JK.Common.DateTimeProviders; +/// public sealed class DefaultDateTimeProvider : IDateTimeProvider { + /// public DateTime Now => DateTime.Now; + + /// public DateTime Today => DateTime.Today; + + /// public DateTime UtcNow => DateTime.UtcNow; } diff --git a/src/JK.Common/Extensions/BooleanExtensions.cs b/src/JK.Common/Extensions/BooleanExtensions.cs index 5486014..a9f123c 100644 --- a/src/JK.Common/Extensions/BooleanExtensions.cs +++ b/src/JK.Common/Extensions/BooleanExtensions.cs @@ -1,5 +1,8 @@ namespace JK.Common.Extensions; +/// +/// Helper and utility extension methods for . +/// public static class BooleanExtensions { public static string ConvertToText(this bool value, in string trueText = "Yes", in string falseText = "No") diff --git a/src/JK.Common/Extensions/ConcurrentBagExtensions.cs b/src/JK.Common/Extensions/ConcurrentBagExtensions.cs index 31d99bc..ad1342d 100644 --- a/src/JK.Common/Extensions/ConcurrentBagExtensions.cs +++ b/src/JK.Common/Extensions/ConcurrentBagExtensions.cs @@ -3,6 +3,9 @@ namespace JK.Common.Extensions; +/// +/// Helper and utility extension methods for . +/// public static class ConcurrentBagExtensions { public static void AddRange(this ConcurrentBag bag, in IEnumerable list) diff --git a/src/JK.Common/Extensions/DateOnlyExtensions.cs b/src/JK.Common/Extensions/DateOnlyExtensions.cs index f22c166..2b6f2e6 100644 --- a/src/JK.Common/Extensions/DateOnlyExtensions.cs +++ b/src/JK.Common/Extensions/DateOnlyExtensions.cs @@ -3,8 +3,11 @@ namespace JK.Common.Extensions; -#if (NET6_0_OR_GREATER) +#if NET6_0_OR_GREATER +/// +/// Helper and utility extension methods for . +/// public static class DateOnlyExtensions { /// Adds given number of business days to a date. diff --git a/src/JK.Common/Extensions/EnumerableExtensions.cs b/src/JK.Common/Extensions/EnumerableExtensions.cs index 3750373..4a1e422 100644 --- a/src/JK.Common/Extensions/EnumerableExtensions.cs +++ b/src/JK.Common/Extensions/EnumerableExtensions.cs @@ -1,4 +1,4 @@ -#if (!NET6_0_OR_GREATER) +#if !NET6_0_OR_GREATER using JK.Common.TypeHelpers; #endif @@ -8,9 +8,12 @@ namespace JK.Common.Extensions; +/// +/// Helper and utility extension methods for . +/// public static class EnumerableExtensions { -#if (!NET6_0_OR_GREATER) +#if !NET6_0_OR_GREATER public static IEnumerable DistinctBy(this IEnumerable source, Func selector) { var comparer = ProjectionComparer.CompareBy(selector, EqualityComparer.Default); diff --git a/src/JK.Common/Extensions/ClassExtensions.cs b/src/JK.Common/Extensions/ObjectExtensions.cs similarity index 57% rename from src/JK.Common/Extensions/ClassExtensions.cs rename to src/JK.Common/Extensions/ObjectExtensions.cs index 006e2f0..f9ffcfe 100644 --- a/src/JK.Common/Extensions/ClassExtensions.cs +++ b/src/JK.Common/Extensions/ObjectExtensions.cs @@ -1,6 +1,9 @@ namespace JK.Common.Extensions; -public static class ClassExtensions +/// +/// Helper and utility extension methods for . +/// +public static class ObjectExtensions { public static bool IsNull(this T value) => value is null; diff --git a/src/JK.Common/Extensions/QueryableExtensions.cs b/src/JK.Common/Extensions/QueryableExtensions.cs index 84bc8d7..376fc5c 100644 --- a/src/JK.Common/Extensions/QueryableExtensions.cs +++ b/src/JK.Common/Extensions/QueryableExtensions.cs @@ -4,6 +4,9 @@ namespace JK.Common.Extensions; +/// +/// Helper and utility extension methods for . +/// public static class QueryableExtensions { public static IQueryable SortBy(this IQueryable source, in Func keySelector, in bool isAscending = true) @@ -35,16 +38,16 @@ public static IQueryable SortBy(this IQueryable source, in string prope return source; } - ParameterExpression parameter = Expression.Parameter(source.ElementType, string.Empty); - MemberExpression property = Expression.Property(parameter, propertyName); - LambdaExpression lambda = Expression.Lambda(property, parameter); + var parameter = Expression.Parameter(source.ElementType, string.Empty); + var property = Expression.Property(parameter, propertyName); + var lambda = Expression.Lambda(property, parameter); var methodName = ascending ? "OrderBy" : "OrderByDescending"; Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName, - new[] { source.ElementType, property.Type }, + [source.ElementType, property.Type], source.Expression, Expression.Quote(lambda)); return source.Provider.CreateQuery(methodCallExpression); @@ -57,6 +60,8 @@ public static IQueryable WhereIf(this IQueryable sour throw new ArgumentNullException(nameof(source)); } - return condition ? source.Where(predicate) : source; + return condition + ? source.Where(predicate) + : source; } } diff --git a/src/JK.Common/Extensions/TypeExtensions.cs b/src/JK.Common/Extensions/TypeExtensions.cs index 80e3338..4657057 100644 --- a/src/JK.Common/Extensions/TypeExtensions.cs +++ b/src/JK.Common/Extensions/TypeExtensions.cs @@ -4,6 +4,9 @@ namespace JK.Common.Extensions; +/// +/// Helper and utility extension methods for . +/// public static class TypeExtensions { /// @@ -20,6 +23,11 @@ public static bool DoesImplement(this Type type) : throw new ArgumentException("Only interfaces can be passed as T."); } + /// + /// Attempts to get the underlying from an Entity Framework proxied type. + /// + /// Suspected DynamicProxy type. + /// Underlying entity . public static Type GetTypeFromEntity(this Type type) { if (type.BaseType is not null && type.Namespace == "System.Data.Entity.DynamicProxies") @@ -29,10 +37,17 @@ public static Type GetTypeFromEntity(this Type type) return type; } + /// + /// Determines whether or not a type is nullable (including , aka T?) + /// + /// The type to check + /// True if nullable, otherwise false + public static bool IsNullable(this Type type) => TypeHelper.IsNullable(type); + /// /// Determines whether or not a type uses , aka T? /// /// The type to check /// True if , otherwise false - public static bool IsNullable(this Type type) => TypeHelper.IsNullable(type); + public static bool IsNullableT(this Type type) => TypeHelper.IsNullableT(type); } diff --git a/src/JK.Common/TypeHelpers/RegexHelper.cs b/src/JK.Common/TypeHelpers/RegexHelper.cs index 0fb1c61..f52f93e 100644 --- a/src/JK.Common/TypeHelpers/RegexHelper.cs +++ b/src/JK.Common/TypeHelpers/RegexHelper.cs @@ -55,9 +55,7 @@ public static partial class RegexHelper private static partial Regex ZipCodeRegex(); } -#endif - -#if !NET7_0_OR_GREATER +#else public static partial class RegexHelper { diff --git a/src/JK.Common/TypeHelpers/StringHelper.cs b/src/JK.Common/TypeHelpers/StringHelper.cs index 17485c9..5fa9d54 100644 --- a/src/JK.Common/TypeHelpers/StringHelper.cs +++ b/src/JK.Common/TypeHelpers/StringHelper.cs @@ -4,6 +4,9 @@ namespace JK.Common.TypeHelpers; +/// +/// Helper and utility methods for . +/// public static class StringHelper { public static decimal? GetNullableDecimal(in string value) @@ -13,7 +16,9 @@ public static class StringHelper return null; } - return !decimal.TryParse(value, out var number) ? null : number; + return !decimal.TryParse(value, out var number) + ? null + : number; } public static int? GetNullableInteger(in string value) @@ -23,7 +28,9 @@ public static class StringHelper return null; } - return !int.TryParse(value, out var number) ? null : number; + return !int.TryParse(value, out var number) + ? null + : number; } /// Returns the specified number of characters from a string. Same as Right() @@ -32,21 +39,23 @@ public static class StringHelper /// Returns the last X characters of the string. public static string Last(in string value, in int length) => Right(value, length); + /// Attemptes to remove United States currency formatting from a string. + /// Value to remove US currency + /// String with US currency formatting stripped. + /// Thrown if given value is whitespace or null. public static string RemoveUnitedStatesCurrencyFormat(in string valueToFormat) { - if (string.IsNullOrEmpty(valueToFormat)) + if (string.IsNullOrWhiteSpace(valueToFormat)) { throw new ArgumentNullException(nameof(valueToFormat)); } var returnValue = valueToFormat.Trim("$".ToCharArray()); returnValue = returnValue.Replace(",", string.Empty); - return string.IsNullOrEmpty(returnValue) ? "0" : returnValue; + return string.IsNullOrWhiteSpace(returnValue) ? "0" : returnValue; } - /// - /// Reverses the characters within a string. - /// + /// Reverses the characters within a string. /// Current string object from extension method. /// The original string in reverse. public static string Reverse(in string valueToReverse) @@ -73,9 +82,7 @@ var v when string.IsNullOrEmpty(v) => string.Empty, _ => value, }; - /// - /// Removes XML/HTML from given text block. - /// + /// Removes XML/HTML from given text block. /// Current string object from extension method. /// Clean string with no XML/HTML. public static string StripXml(in string valueToStrip) => Regex.Replace(valueToStrip, @"<(.|\n)*?>", string.Empty); @@ -117,7 +124,7 @@ public static string ToBase64(in string text) public static ReadOnlySpan Slice(in string text, int start) { ReadOnlySpan textAsSpan = text; - return textAsSpan.Slice(start); + return textAsSpan[start..]; } public static ReadOnlySpan Slice(in string text, int start, int length) diff --git a/src/JK.Common/TypeHelpers/TypeHelper.cs b/src/JK.Common/TypeHelpers/TypeHelper.cs index 5f01d70..f02e72a 100644 --- a/src/JK.Common/TypeHelpers/TypeHelper.cs +++ b/src/JK.Common/TypeHelpers/TypeHelper.cs @@ -2,19 +2,49 @@ namespace JK.Common.TypeHelpers; +/// +/// Class which contains helper and utility methods for +/// public static class TypeHelper { + /// + /// Determines whether or not a type is nullable (including , aka T?) + /// + /// The type to check + /// True if nullable, otherwise false + public static bool IsNullable(in Type type) + => !type.IsValueType || IsNullableT(type); + + /// + /// Determines whether or not a type is nullable (including , aka T?) + /// + /// The type to check + /// True if nullable, otherwise false + public static bool IsNullable() + => IsNullable(typeof(T)); + + /// + /// Determines whether or not a type is nullable (including , aka T?) + /// + /// The type to check + /// Value to get type from. + /// True if nullable, otherwise false + public static bool IsNullable(in T value) + => value is null || IsNullable(); + /// /// Determines whether or not a type uses , aka T? /// /// The type to check /// True if , otherwise false - public static bool IsNullable(in Type type) => Nullable.GetUnderlyingType(type) != null; + public static bool IsNullableT(in Type type) + => Nullable.GetUnderlyingType(type) != null; /// /// Determines whether or not a type uses , aka T? /// /// The type to check /// True if , otherwise false - public static bool IsNullable() => IsNullable(typeof(T)); + public static bool IsNullableT() + => IsNullableT(typeof(T)); }