有各种文章,例如 msdn.microsoft.com/en-us/library/ms379570(v=vs.80).aspx,似乎表明通用 List 的项是存储在连续的内存中。然而,我无法找到任何明确的陈述来证明这一点,无论是肯定还是否定。有人知道吗?请注意,很清楚地指出数组是连续的,但这个问题适用于List。
此外,有没有办法直接访问 List 使用的内存?
public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>
{
private const int _defaultCapacity = 4;
private T[] _items;
List<T>
包含一个 T[]
数组,所以如果数组是连续的(是的),那么 List<T>
也是连续的 :-)public static class ArrayFromList
{
public static FieldInfo GetField<T>()
{
return ArrayFromListImpl<T>.Field;
}
public static T[] GetArray<T>(List<T> list)
{
return ArrayFromListImpl<T>.GetArray(list);
}
public static class ArrayFromListImpl<T>
{
public static readonly FieldInfo Field;
public static readonly Func<List<T>, T[]> GetArray;
static ArrayFromListImpl()
{
Field = typeof(List<T>)
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.Where(x => x.FieldType == typeof(T[]))
.Single();
var par = Expression.Parameter(typeof(List<T>));
var exp = Expression.Lambda<Func<List<T>, T[]>>(Expression.Field(par, Field), par);
GetArray = exp.Compile();
}
}
}
使用方法如下:
var lst = new List<int> { 1, 2, 3 };
var ptr = ArrayFromList.GetArray(lst);
List<T>
上不起作用,因为它将数组隐藏在子对象中 :-)(但在.NET和Mono上可以工作:-))T
是引用类型,那么句柄在内存中将是连续的,但实际对象不会连续。 - Lucas Trzesniewski_items
:-) 然后使用一些技巧来缓存对该数组的访问,以便于每种 List<T>
类型只使用一次反射,而连续使用则不再需要。请记住,该数组可能比 List<T>
的 Count
更大! - xanatos