Files
QWERTYkez.Mensura/QWERTYkez.Mensura/Extensions/CastExtensions.cs
melekhin c27c2e0085 26.06.03
2026-06-03 12:07:27 +07:00

56 lines
2.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace QWERTYkez.Mensura.Extensions;
public static partial class CastExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static double ToDouble<T>(this T unit)
where T : struct, IMensuraUnit, IEquatable<T>
{
return Unsafe.As<T, double>(ref unit);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T ToUnit<T>(this double val)
where T : struct, IMensuraUnit, IEquatable<T>
{
return Unsafe.As<double, T>(ref val);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void SetCountUnsafe<T>(this List<T> list, int count)
{
// Берем адрес управляемого объекта List в памяти
// Объект передается по ref-ссылке, преобразуется в указатель
ref var mimic = ref Unsafe.As<List<T>, ListLayoutMimic<T>>(ref list);
// Меняем приватный размер напрямую в памяти объекта!
mimic.Size = count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static List<T> WrapAsList<T>(this T[] array)
{
// Создаём пустой список с нулевой ёмкостью
var list = new List<T>(0);
// Получаем внутреннюю структуру списка
ref var mimic = ref Unsafe.As<List<T>, ListLayoutMimic<T>>(ref list);
// Подменяем массив и устанавливаем размер
mimic.Items = array;
mimic.Size = array.Length;
mimic.Version = 1; // любое ненулевое значение для консистенции
return list;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static List<R> WrapAsList<T, R>(this T[] array)
where T : struct, IMensuraUnit, IEquatable<T>
where R : struct, IMensuraUnit, IEquatable<R>
{
return Unsafe.As<T[], R[]>(ref array).WrapAsList();
}
}