removed some new lang features to support net6.0 and net7.0
All checks were successful
.NET Test / test (push) Successful in 1m5s
.NET Publish / publish (push) Successful in 51s

This commit is contained in:
2023-12-15 12:37:39 +04:00
parent c02fdc5492
commit 57e83fbafa
7 changed files with 76 additions and 60 deletions

View File

@@ -10,58 +10,58 @@ internal static class ReflectionHelper
[Pure, MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Compare<T>(T? left, T? right) => TypeReflectionCache<T>.CompareFunc(left, right);
}
file static class TypeReflectionCache<T>
{
public static readonly Func<T?, T?, bool> IsEqualFunc;
public static readonly Func<T?, T?, int> CompareFunc;
static TypeReflectionCache()
private static class TypeReflectionCache<T>
{
var type = typeof(T);
var isNullableStruct = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
var underlyingType = isNullableStruct ? type.GenericTypeArguments.First() : type;
var thisType = typeof(TypeReflectionCache<T>);
public static readonly Func<T?, T?, bool> IsEqualFunc;
public static readonly Func<T?, T?, int> 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<T>);
IsEqualFunc = (Func<T?, T?, bool>)Delegate.CreateDelegate(typeof(Func<T?, T?, bool>), 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<T?, T?, bool>)Delegate.CreateDelegate(typeof(Func<T?, T?, bool>), 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<T?, T?, int>)Delegate.CreateDelegate(typeof(Func<T?, T?, int>), 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>(R? left, R? right) where R : notnull, IEquatable<R>, T => left is null ? right is null : left.Equals(right);
[Pure] public static bool IsEqualNullable<R>(R? left, R? right) where R : struct, IEquatable<R> => left is null ? right is null : right is not null && left.Value.Equals(right.Value);
CompareFunc = (Func<T?, T?, int>)Delegate.CreateDelegate(typeof(Func<T?, T?, int>), 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>(R? left, R? right) where R : notnull, IComparable<R>, T => left is null
? right is null ? 0 : -1
: right is null ? 1 : left.CompareTo(right);
[Pure] public static int CompareNullable<R>(R? left, R? right) where R : struct, IComparable<R> => 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>(R? left, R? right) where R : notnull, IEquatable<R>, T => left is null ? right is null : left.Equals(right);
[Pure] public static bool IsEqualNullable<R>(R? left, R? right) where R : struct, IEquatable<R> => left is null ? right is null : right is not null && left.Value.Equals(right.Value);
[Pure] public static int Compare<R>(R? left, R? right) where R : notnull, IComparable<R>, T => left is null
? right is null ? 0 : -1
: right is null ? 1 : left.CompareTo(right);
[Pure] public static int CompareNullable<R>(R? left, R? right) where R : struct, IComparable<R> => 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.
}