Advertisement
Enderlook

CastHelper

Mar 23rd, 2025 (edited)
377
0
363 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.81 KB | None | 0 0
  1. public abstract class CasterHelper<TFrom, TTo>
  2. #if NET9_0_OR_GREATER
  3.     where TFrom : allows ref struct
  4.     where TTo : allows ref struct
  5. #endif
  6. {
  7. #if NET9_0_OR_GREATER
  8.     private static readonly CasterHelper<TFrom, TTo>? Impl = (typeof(TFrom).IsByRefLike || typeof(TTo).IsByRefLike || (typeof(TFrom).IsValueType && typeof(TTo) == typeof(TFrom)))
  9.         ? null
  10.         : (CasterHelper<TFrom, TTo>?)Activator.CreateInstance(typeof(CastHelperImplementation<,>).MakeGenericType(new Type[] { typeof(TFrom), typeof(TTo) }));
  11. #endif
  12.  
  13.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
  14.     [return: NotNullIfNotNull(nameof(from))]
  15.     public static TTo Cast(scoped in TFrom from)
  16.     {
  17.         if (typeof(TFrom).IsValueType && typeof(TFrom) == typeof(TTo))
  18.         {
  19. #if NET9_0_OR_GREATER
  20.             return Unsafe.BitCast<TFrom, TTo>(from);
  21. #else
  22.             return Unsafe.As<TFrom, TTo>(ref Unsafe.AsRef(in from));
  23. #endif
  24.         }
  25.  
  26. #if NET9_0_OR_GREATER
  27.         if (typeof(TFrom).IsByRefLike || typeof(TTo).IsByRefLike)
  28.             Helper.ThrowInvalidCastException();
  29. #endif
  30.  
  31. #if NET9_0_OR_GREATER
  32.         return Impl!.Cast_(from);
  33. #else
  34.         return (TTo)(object)from;
  35. #endif
  36.     }
  37.  
  38.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
  39.     public static bool TryCast(scoped in TFrom from, out TTo? to)
  40.     {
  41.         if (typeof(TFrom).IsValueType && typeof(TFrom) == typeof(TTo))
  42.         {
  43. #if NET9_0_OR_GREATER
  44.             to = Unsafe.BitCast<TFrom, TTo>(from);
  45. #else
  46.             to = Unsafe.As<TFrom, TTo>(ref Unsafe.AsRef(in from));
  47. #endif
  48.             return true;
  49.         }
  50.  
  51. #if NET9_0_OR_GREATER
  52.         if (typeof(TFrom).IsByRefLike || typeof(TTo).IsByRefLike)
  53.         {
  54.             to = default;
  55.             return false;
  56.         }
  57. #endif
  58.  
  59. #if NET9_0_OR_GREATER
  60.         return Impl!.TryCast_(from, out to);
  61. #else
  62.         if (from is TTo v)
  63.         {
  64.             to = v;
  65.             return true;
  66.         }
  67.         to = default;
  68.         return !typeof(TTo).IsValueType && from is null;
  69. #endif
  70.     }
  71.  
  72. #if NET9_0_OR_GREATER
  73.     [return: NotNullIfNotNull(nameof(from))]
  74.     protected abstract TTo Cast_(scoped in TFrom from);
  75.  
  76.     protected abstract bool TryCast_(scoped in TFrom from, out TTo to);
  77. #endif
  78. }
  79.  
  80. #if NET9_0_OR_GREATER
  81. internal sealed class CastHelperImplementation<TFrom, TTo> : CasterHelper<TFrom, TTo>
  82. {
  83.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
  84.     protected override TTo Cast_(scoped in TFrom from) => (TTo)(object)from;
  85.  
  86.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
  87.     protected override bool TryCast_(scoped in TFrom from, out TTo to)
  88.     {
  89.         if (from is TTo v)
  90.         {
  91.             to = v;
  92.             return true;
  93.         }
  94.         to = default;
  95.         return !typeof(TTo).IsValueType && from is null;
  96.     }
  97. }
  98. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement