代码之家  ›  专栏  ›  技术社区  ›  satnhak

LINQ查询是否使用欠列数据类型?

  •  1
  • satnhak  · 技术社区  · 14 年前

    例如,考虑:

    var hset = new HashSet<int>();
    // Fill the hset.
    
    var enumerable = hset as IEnumerable<int>;
    bool enumerable.Contains(0);
    

    linq是否使用hashset具有有效的 Contains 或者它是否意味着像我们所期望的那样对枚举器进行操作?

    我问的原因是我目前正在处理的组件有许多属性 IEnumerable<T> 但是,以前的开发人员总是在将可枚举对象分配给属性之前将其用于创建可枚举对象的任何数据结构转换为数组。我不确定这是好的做法还是完全浪费时间。

    5 回复  |  直到 14 年前
        1
  •  7
  •   driis    14 年前

    有一些适当的优化,contains就是其中之一。

    现在,当我们有了Microsoft公共符号服务器时,我们可以在有疑问时查看代码。这是 Enumerable.Contains 在.NET Framework 4中:

    public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value) 
    { 
        ICollection<TSource> collection = source as ICollection<TSource>;
        if (collection != null) return collection.Contains(value); 
        return Contains<TSource>(source, value, null);
    }
    

    方法将源强制转换为 ICollection<T> 成功时,使用它 Contains 方法。自从 HashSet<T> 器具 i收集<t> ,实际使用的方法是 HashSet<T>.Contains . 这很好,因为与数组o(n)相比,它是一个o(1)操作。

    换句话说,首先转换为数组会损害性能:复制操作首先需要时间,然后实际的查找将不那么有效,o(n),因为contains方法需要查看数组的所有元素。

    一般来说,当浏览Enumerable.cs时,通常使用这种模式:大多数方法尝试使用方法的ICollection版本,而这样做会有好处。

        2
  •  1
  •   Greg    14 年前

    LINQ扩展方法 Contains 具有实现的可枚举项的快捷方式 ICollection<> . 自从 HashSet<> 器具 i收集<> ,它将进行有效的查找。

    Documented in MSDN

    如果源类型实现了ICollection(of T),则将调用该实现中的contains方法以获取结果。否则,此方法将确定源是否包含指定的元素。

    使用反射镜可验证

    public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value)
    {
        ICollection<TSource> is2 = source as ICollection<TSource>;
        if (is2 != null)
        {
            return is2.Contains(value);
        }
        return source.Contains<TSource>(value, null);
    }
    
        3
  •  0
  •   adrianbanks    14 年前

    林肯 Contains 扩展方法会检查类型并执行相关的操作。如果可枚举实现 ICollection<T> 它的 ICollection<T>.Contains() 将调用方法。如果不是,则将使用 foreach 直到找到指定的项目。

    自从 HashSet<T> 器具 i收集<t> , the 包含 将调用方法。

        4
  •  0
  •   Ray Henry    14 年前

    如果源类型实现ICollection,则调用该实现中的contains方法以获取结果。否则,此方法将确定源是否包含指定的元素。

    http://msdn.microsoft.com/en-us/library/bb352880.aspx

        5
  •  0
  •   Community Romance    7 年前

    这要看情况而定。某些方法会检查特定的 界面 在使用“最小公分母”实现(仅使用 IEnumerable<T> 接口。

    例如, Count 两者都要检查 ICollection ICollection<T> 为了在一个接一个地计算所有元素之前利用(大概)O(1)计数。

    似乎来自 driis's answer 那个 Contains 也是这样,检查 i收集<t> (哪个) HashSet<T> 工具)。

    现在,我不清楚你的意思是什么:

    [上一个开发人员]在将可枚举对象分配给属性之前,始终将其用于创建可枚举对象的任何数据结构转换为数组。

    如果您的意思是您的集合实际上被复制到数组中,以便作为 IEnumerable<t> 那么你肯定是 得到 哈希集<t> 班的 包含 方法;你得到 数组 (自) T[] 数组不实现 i收集<t> 尽管这真的不会比幼稚的方法更好)。