namespace Zinnia.Extension { using System; using System.Collections.Generic; using System.Reflection; using UnityEngine; /// /// Extended methods for sorting s. /// /// The type of the elements. public static class ArraySortExtensions { /// /// Whether a heap allocation free sort is available. /// public static bool IsHeapAllocationFreeSortAvailable => sortAction != null; /// /// The cached delegate of the sort method to call. /// private static readonly Action> sortAction; static ArraySortExtensions() { const string fullTypeName = "System.Collections.Generic.ArraySortHelper`1"; const string methodName = "Sort"; Type type = typeof(Array).Assembly.GetType(fullTypeName); Type genericType = type?.MakeGenericType(typeof(T)); MethodInfo methodInfo = genericType?.GetMethod( methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(T[]), typeof(int), typeof(int), typeof(Comparison) }, null); if (methodInfo == null) { sortAction = null; Debug.LogWarning($"No heap allocation free sort is available: Type '{fullTypeName}' wasn't found" + $" or the method '{methodName}' doesn't have the expected signature." + " Sorting will fall back to the implementation that will create heap allocations."); return; } sortAction = (Action>)Delegate.CreateDelegate( typeof(Action>), methodInfo); } /// /// Sorts the elements in a one-dimensional array. /// /// The array to sort. /// The starting index of the range to sort. /// The number of elements in the range to sort. /// The implementation to use when comparing elements. Will only be used if is . /// The implementation to use when comparing elements. Will only be used if is . public static void Sort(T[] array, int index, int length, IComparer comparer, Comparison comparison) { if (sortAction == null) { Array.Sort(array, index, length, comparer); return; } sortAction(array, index, length, comparison); } } }