有各种文章,例如msdn.microsoft.com/en-us/library/ms379570(v=vs.80).aspx,这似乎表明通用列表的项目存储在连续的内存中。但无论如何,我无法找到任何明确的声明。有谁知道一个。请注意,非常清楚地表明数组是连续的,但此问题适用于List。
还有什么方法可以直接访问List使用的内存吗?
答案 0 :(得分:7)
List<T>的来源非常明确:
public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>
{
private const int _defaultCapacity = 4;
private T[] _items;
List<T>
包含T
(T[]
)数组,所以如果数组是连续的(是的,它是),那么List<T>
是连续的:-)
来自List<T> MSDN页面:
List类是ArrayList类的通用等价物。 它通过使用大小根据需要动态增加的数组来实现IList通用接口。
关于第二个问题:
还有什么方法可以直接访问List使用的内存吗?
你似乎更像是一个理论&#34;程序员,所以答案是否定的。对于&#34;实用&#34;正在读这篇的程序员,他们可以使用:
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);
请注意,这不会对#34;理论和#34; List<T>
&#34;隐藏&#34;子对象中的数组:-)(但可以在.NET和Mono上工作:-))