diff --git a/Railway/Ensure.cs b/Railway/Ensure.cs index 2558b35..2d7c171 100644 --- a/Railway/Ensure.cs +++ b/Railway/Ensure.cs @@ -60,6 +60,7 @@ public readonly struct Ensure Value = value; ValueExpression = valueExpression; State = ResultState.Success; + Error = default; } internal Ensure(Error error, string valueExpression) @@ -72,7 +73,12 @@ public readonly struct Ensure } [Serializable] -public class EnsureNotInitializedException(string variableName = "this") : InvalidOperationException("Ensure was not properly initialized.") +public class EnsureNotInitializedException : InvalidOperationException { - public string VariableName { get; } = variableName; + public EnsureNotInitializedException(string variableName = "this") + : base("Ensure was not properly initialized.") + { + VariableName = variableName; + } + public string VariableName { get; } } diff --git a/Railway/Error.cs b/Railway/Error.cs index c46a583..d22cad3 100644 --- a/Railway/Error.cs +++ b/Railway/Error.cs @@ -52,7 +52,7 @@ public abstract class Error : IEquatable, IComparable [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)] public static Error Many(Error error1, Error error2) => (error1, error2) switch { - (null, null) => new ManyErrors([]), + (null, null) => new ManyErrors(new List()), (Error err, null) => err, (Error err, { IsEmpty: true }) => err, (null, Error err) => err, @@ -231,7 +231,7 @@ public sealed class ExceptionalError : Error var valueString = value.ToString(); if (string.IsNullOrEmpty(keyString) || string.IsNullOrEmpty(valueString)) continue; - values ??= []; + values ??= new List>(4); values.Add(new(keyString, valueString)); } return values?.ToImmutableDictionary() ?? ImmutableDictionary.Empty; @@ -377,7 +377,11 @@ public sealed class ManyErrors : Error, IEnumerable, IReadOnlyList } [Serializable] -public sealed class ErrorException(string type, string message) : Exception(message) +public sealed class ErrorException : Exception { - public string Type { get; } = type ?? nameof(ErrorException); + public ErrorException(string type, string message) : base(message) + { + Type = type ?? nameof(ErrorException); + } + public string Type { get; } } diff --git a/Railway/ErrorJsonConverter.cs b/Railway/ErrorJsonConverter.cs index 8842c2d..76b3271 100644 --- a/Railway/ErrorJsonConverter.cs +++ b/Railway/ErrorJsonConverter.cs @@ -35,7 +35,7 @@ public sealed class ErrorJsonConverter : JsonConverter internal static ManyErrors ReadMany(ref Utf8JsonReader reader) { - List errors = []; + List errors = new(4); while (reader.Read()) { if (reader.TokenType == JsonTokenType.StartObject) @@ -83,7 +83,7 @@ public sealed class ErrorJsonConverter : JsonConverter } else if (!string.IsNullOrEmpty(propname)) { - extensionData ??= []; + extensionData ??= new(4); extensionData.Add(new(propname, propvalue)); } diff --git a/Railway/Railway.csproj b/Railway/Railway.csproj index 0cb22bd..5692e96 100644 --- a/Railway/Railway.csproj +++ b/Railway/Railway.csproj @@ -1,7 +1,8 @@ - net8.0 + net6.0;net7.0;net8.0 + 10.0 enable enable Just.Railway @@ -13,7 +14,6 @@ Copyright (c) 2023 JustFixMe LICENSE README.md - https://github.com/JustFixMe/Just.Railway/ true diff --git a/Railway/ReflectionHelper.cs b/Railway/ReflectionHelper.cs index bd449da..e269e09 100644 --- a/Railway/ReflectionHelper.cs +++ b/Railway/ReflectionHelper.cs @@ -10,58 +10,58 @@ internal static class ReflectionHelper [Pure, MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Compare(T? left, T? right) => TypeReflectionCache.CompareFunc(left, right); -} -file static class TypeReflectionCache -{ - public static readonly Func IsEqualFunc; - public static readonly Func CompareFunc; - - static TypeReflectionCache() + private static class TypeReflectionCache { - var type = typeof(T); - var isNullableStruct = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); - var underlyingType = isNullableStruct ? type.GenericTypeArguments.First() : type; - var thisType = typeof(TypeReflectionCache); + public static readonly Func IsEqualFunc; + public static readonly Func CompareFunc; - var equatableType = typeof(IEquatable<>).MakeGenericType(underlyingType); - if (equatableType.IsAssignableFrom(underlyingType)) + static TypeReflectionCache() { - var isEqualFunc = thisType.GetMethod(isNullableStruct ? nameof(IsEqualNullable) : nameof(IsEqual), BindingFlags.Static | BindingFlags.Public) - !.MakeGenericMethod(underlyingType); + var type = typeof(T); + var isNullableStruct = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + var underlyingType = isNullableStruct ? type.GenericTypeArguments.First() : type; + var thisType = typeof(TypeReflectionCache); - IsEqualFunc = (Func)Delegate.CreateDelegate(typeof(Func), isEqualFunc); - } - else - { - IsEqualFunc = static (left, right) => left is null ? right is null : left.Equals(right); + var equatableType = typeof(IEquatable<>).MakeGenericType(underlyingType); + if (equatableType.IsAssignableFrom(underlyingType)) + { + var isEqualFunc = thisType.GetMethod(isNullableStruct ? nameof(IsEqualNullable) : nameof(IsEqual), BindingFlags.Static | BindingFlags.Public) + !.MakeGenericMethod(underlyingType); + + IsEqualFunc = (Func)Delegate.CreateDelegate(typeof(Func), isEqualFunc); + } + else + { + IsEqualFunc = static (left, right) => left is null ? right is null : left.Equals(right); + } + + var comparableType = typeof(IComparable<>).MakeGenericType(underlyingType); + if (comparableType.IsAssignableFrom(underlyingType)) + { + var compareFunc = thisType.GetMethod(isNullableStruct ? nameof(CompareNullable) : nameof(Compare), BindingFlags.Static | BindingFlags.Public) + !.MakeGenericMethod(underlyingType); + + CompareFunc = (Func)Delegate.CreateDelegate(typeof(Func), compareFunc); + } + else + { + CompareFunc = static (left, right) => left is null + ? right is null ? 0 : -1 + : right is null ? 1 : left.GetHashCode().CompareTo(right.GetHashCode()); + } } - var comparableType = typeof(IComparable<>).MakeGenericType(underlyingType); - if (comparableType.IsAssignableFrom(underlyingType)) - { - var compareFunc = thisType.GetMethod(isNullableStruct ? nameof(CompareNullable) : nameof(Compare), BindingFlags.Static | BindingFlags.Public) - !.MakeGenericMethod(underlyingType); + #pragma warning disable CS8604 // Possible null reference argument. + [Pure] public static bool IsEqual(R? left, R? right) where R : notnull, IEquatable, T => left is null ? right is null : left.Equals(right); + [Pure] public static bool IsEqualNullable(R? left, R? right) where R : struct, IEquatable => left is null ? right is null : right is not null && left.Value.Equals(right.Value); - CompareFunc = (Func)Delegate.CreateDelegate(typeof(Func), compareFunc); - } - else - { - CompareFunc = static (left, right) => left is null - ? right is null ? 0 : -1 - : right is null ? 1 : left.GetHashCode().CompareTo(right.GetHashCode()); - } + [Pure] public static int Compare(R? left, R? right) where R : notnull, IComparable, T => left is null + ? right is null ? 0 : -1 + : right is null ? 1 : left.CompareTo(right); + [Pure] public static int CompareNullable(R? left, R? right) where R : struct, IComparable => left is null + ? right is null ? 0 : -1 + : right is null ? 1 : left.Value.CompareTo(right.Value); + #pragma warning restore CS8604 // Possible null reference argument. } - -#pragma warning disable CS8604 // Possible null reference argument. - [Pure] public static bool IsEqual(R? left, R? right) where R : notnull, IEquatable, T => left is null ? right is null : left.Equals(right); - [Pure] public static bool IsEqualNullable(R? left, R? right) where R : struct, IEquatable => left is null ? right is null : right is not null && left.Value.Equals(right.Value); - - [Pure] public static int Compare(R? left, R? right) where R : notnull, IComparable, T => left is null - ? right is null ? 0 : -1 - : right is null ? 1 : left.CompareTo(right); - [Pure] public static int CompareNullable(R? left, R? right) where R : struct, IComparable => left is null - ? right is null ? 0 : -1 - : right is null ? 1 : left.Value.CompareTo(right.Value); -#pragma warning restore CS8604 // Possible null reference argument. } diff --git a/Railway/Result.cs b/Railway/Result.cs index bfcab13..aa2ae89 100644 --- a/Railway/Result.cs +++ b/Railway/Result.cs @@ -136,6 +136,7 @@ public readonly struct Result : IEquatable> { Value = value; State = ResultState.Success; + Error = default; } [Pure] public static explicit operator Result(Result result) => result.State switch @@ -263,7 +264,12 @@ public readonly struct SuccessUnit : IEquatable } [Serializable] -public class ResultNotInitializedException(string variableName = "this") : InvalidOperationException("Result was not properly initialized.") +public class ResultNotInitializedException : InvalidOperationException { - public string VariableName { get; } = variableName; + public ResultNotInitializedException(string variableName = "this") + : base("Result was not properly initialized.") + { + VariableName = variableName; + } + public string VariableName { get; } } diff --git a/Railway/ResultExtensions.cs b/Railway/ResultExtensions.cs index 34576c5..9a41900 100644 --- a/Railway/ResultExtensions.cs +++ b/Railway/ResultExtensions.cs @@ -89,7 +89,7 @@ public static partial class ResultExtensions { case ResultState.Error: hasErrors = true; - errors ??= []; + errors ??= new(4); errors.Add(result.Error!); break; @@ -123,13 +123,13 @@ public static partial class ResultExtensions { case ResultState.Error: hasErrors = true; - errors ??= []; + errors ??= new(4); errors.Add(result.Error!); break; case ResultState.Success: if (hasErrors) goto afterLoop; - values ??= []; + values ??= new(4); values.Add(result.Value); break;