C# 优化泛型扩展方法

C# 优化泛型扩展方法,c#,extension-methods,C#,Extension Methods,我可以更高效地编写这些函数吗 public static void AddDistinct<T>(this ICollection<T> source, params ICollection<T>[] collections) { (from collection in collections from item in collection where !source.Contains(item) select item).ForEach(source

我可以更高效地编写这些函数吗

public static void AddDistinct<T>(this ICollection<T> source, params ICollection<T>[] collections)
{
    (from collection in collections from item in collection where !source.Contains(item) select item).ForEach(source.Add);
}

public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params ICollection<T>[] collections)
{
    collections.ForEach(collection => collection.Where(predicate).Where(item => !source.Contains(item)).ForEach(source.Add));
}

public static void AddDistinct<T>(this ICollection<T> source, params T[] items)
{
    items.Where(item => !source.Contains(item)).ForEach(source.Add);
}

public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params T[] items)
{
    items.Where(predicate).Where(x => !source.Contains(x)).ForEach(source.Add);
}
您可以使用Except方法:

请注意,由于Where和Except具有延迟和流式执行,因此在添加任何内容之前,您需要ToArray调用以确保源的枚举已完成,因为在枚举集合时无法修改该集合。

您可以使用Except方法:


请注意,由于Where和Except具有延迟和流式执行,您需要ToArray调用,以确保在添加任何内容之前源的枚举已完成,因为在枚举集合时无法修改它。

是,使用例如哈希集,您可以比在*M上做得更好。

是,例如,使用hashset,你可以比使用*M做得更好。

使用hashset和IEnumerable,我认为你可以做得更有效。哈希集在跟踪重复项方面非常有效,您只需遍历源代码一次即可将其加载到哈希集中。除非我弄错了,我认为ICollection和T[]都是IEnumerables

但不确定您需要这些谓词版本做什么。您不能在添加项目之前对其进行筛选吗?

使用HashSet和IEnumerable,我认为您可以更有效地进行筛选。哈希集在跟踪重复项方面非常有效,您只需遍历源代码一次即可将其加载到哈希集中。除非我弄错了,我认为ICollection和T[]都是IEnumerables


但不确定您需要这些谓词版本做什么。您不能在添加项目之前对其进行筛选吗?

内置的可枚举项。Exception方法可能已经使用了哈希集或类似的东西,而且使用起来更直观…@Thomas:我不知道,我认为它比原始代码简单得多。与Except不同的是,他的答案很容易扩展到许多集合。内置的Enumerable.Except方法可能已经使用了哈希集或类似的东西,而且使用起来更直观…@Thomas:我不知道,我认为比原始代码简单得多。与Except不同的是,他的答案很容易扩展到许多收藏。我同意,我以前可以使用过滤器。我同意,我以前可以使用过滤器。
public static void AddDistinct<T>(this ICollection<T> source, params ICollection<T>[] collections)
{
    var itemsToAdd = collections.SelectMany(x => x).Where(predicate).Except(source).ToArray();
    itemsToAdd.ForEach(source.Add));
}

public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params ICollection<T>[] collections)
{
    var itemsToAdd = collections.SelectMany(x => x).Where(predicate).Except(source).ToArray();
    itemsToAdd.ForEach(source.Add));
}

public static void AddDistinct<T>(this ICollection<T> source, params T[] items)
{
    var itemsToAdd = items.Except(source).ToArray();
    itemsToAdd.ForEach(source.Add));
}

public static void AddDistinct<T>(this ICollection<T> source, Func<T, bool> predicate, params T[] items)
{
    var itemsToAdd = items.Where(predicate).Except(source).ToArray();
    itemsToAdd.ForEach(source.Add));
}
public static void AddDistinct<T>(this ICollection<T> source, params IEnumerable<T> items)
{
    var set = new HashSet<T>(source);
    foreach(var item in items)
    {
        if(set.Add(item))
            source.Add(item);
    }
}