Насколько я знаю, официального способа сделать это не существует, но все еще возможно использовать System.Reflection
.Посмотрев на исходный код List<T>
, .NET Framework 4.7.2 , можно выделить два важных свойства _items
и _size
.Существует также _version
, но он меняется только при изменении List<T>
.Модификации: Add
, AddRange
, Remove
и т. Д., А также Reverse
и Sort
.Итак, давайте предположим, что это та же самая операция, что и при создании списка из IEnumerable<T>
, где _version
остается равным нулю.
public static class ListExtensions
{
public static void SetUnderlyingArray<T>(this List<T> list, T[] array)
{
lock (list)
{
SetInternalArray(list, array);
SetInternalArraySize(list, array.Length);
}
}
private static void SetInternalArraySize<T>(this List<T> list, int size)
{
var prop = list.GetType().GetField(
"_size",
BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(list, size);
}
private static void SetInternalArray<T>(this List<T> list, T[] array)
{
var prop = list.GetType().GetField(
"_items",
BindingFlags.NonPublic | BindingFlags.Instance);
prop.SetValue(list, array);
}
}
, а затем задаем базовый массив
int[] array = Enumerable.Repeat(1, 1000000).ToArray();
List<int> list = new List<int>();
list.SetUnderlyingArray(array);
Примечание Это решение сильно зависит от деталей реализации и может быть неправильным, если что-то изменится во внутренних элементах List<T>
, но оно дает представление о том, как это можно сделать.