在C#中固定IEnumerables

时间:2009-05-21 15:50:26

标签: c#

我想用我正在研究的这种通用扩展方法将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);
    }

为什么某些类型的失败但是为其他类型工作?你能解释一下这背后的概念吗?有没有比我的通用方法更好的方法呢?谢谢。

2 个答案:

答案 0 :(得分:7)

GCHandle.Alloc的{​​{3}}表示:

  

无法固定具有非原始(非blittable)成员的实例。

对象引用不是原始(也称为blittable)成员。像List<T>等类型的实现在内部使用对象引用(例如数组引用)。因此,他们有非原始成员,不能固定。

数组是不同的:如果数组的元素类型是blittable(即没有非blittable字段的值类型),则可以固定数组。但这并不意味着可以固定对阵列的引用;对数组的引用不是数组。像List<T>这样的集合类包含对内部存储阵列的引用。它们本身不是数组。

答案 1 :(得分:1)

如果真的需要这个,我建议您致电.ToArray()并确认。

但要小心,因为IEnumerable本身使用延迟评估/延迟执行,因此可枚举的当前可能根本不在内存中。事实上,你甚至可以拥有一个永不停止的IEnumerable。