我想用我正在研究的这种通用扩展方法将IEnumerable实现固定在内存中。它似乎适用于数组,但与其他序列(列表和集合)失败。这是方法实现。
// <summary>
/// Pins an IEnumerable of type T in memory
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sequence"></param>
/// <returns></returns>
public static GCHandle Pin<T>(this IEnumerable<T> @sequence)
{
return GCHandle.Alloc(@sequence, GCHandleType.Pinned);
}
为什么某些类型的失败但是为其他类型工作?你能解释一下这背后的概念吗?有没有比我的通用方法更好的方法呢?谢谢。
答案 0 :(得分:7)
GCHandle.Alloc
的{{3}}表示:
无法固定具有非原始(非blittable)成员的实例。
对象引用不是原始(也称为blittable)成员。像List<T>
等类型的实现在内部使用对象引用(例如数组引用)。因此,他们有非原始成员,不能固定。
数组是不同的:如果数组的元素类型是blittable(即没有非blittable字段的值类型),则可以固定数组。但这并不意味着可以固定对阵列的引用;对数组的引用不是数组。像List<T>
这样的集合类包含对内部存储阵列的引用。它们本身不是数组。
答案 1 :(得分:1)
如果真的需要这个,我建议您致电.ToArray()
并确认。
但要小心,因为IEnumerable本身使用延迟评估/延迟执行,因此可枚举的值当前可能根本不在内存中。事实上,你甚至可以拥有一个永不停止的IEnumerable。