有没有更简洁的linq方式来'联盟'单项?

时间:2010-08-20 15:07:57

标签: c# linq union

如果我有两个序列并且我想要将它们一起处理,我可以将它们联合起来然后我们离开。

现在假设我有一个项目,我想在两个序列之间处理。我可以通过创建一个包含单个项目的数组来获取它,但是有更简洁的方法吗?即。

var top = new string[] { "Crusty bread", "Mayonnaise" };
string filling = "BTL";
var bottom = new string[] { "Mayonnaise", "Crusty bread" };

// Will not compile, filling is a string, therefore is not Enumerable
//var sandwich = top.Union(filling).Union(bottom);

// Compiles and works, but feels grungy (looks like it might be smelly)
var sandwich = top.Union(new string[]{filling}).Union(bottom);

foreach (var item in sandwich)
    Process(item);

是否有批准的方式,或者这是批准的方式?

由于

4 个答案:

答案 0 :(得分:36)

一种选择是自己超载:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, T item)
{
    return source.Union(Enumerable.Repeat(item, 1));
}

这就是我们在Concat中使用MoreLINQ所做的。

答案 1 :(得分:6)

考虑使用更灵活的方法:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, params T[] items)
{
    return source.Union((IEnumerable<T>)items);
}

适用于单个项目和多个项目。 您也可以接受空source值:

public static IEnumerable<T> Union<T>(this IEnumerable<T> source, params T[] items)
{
    return source != null ? source.Union((IEnumerable<T>)items) : items;
}

答案 2 :(得分:4)

我的代码中往往有以下内容:

public static IEnumerable<T> EmitFromEnum<T>(this T item)
{
  yield return item;
}

虽然将col.Union(obj.EmitFromEnum());称为col.Union(obj)并不是那么干净,但它确实意味着这个单一的扩展方法涵盖了我可能想要这样一个单项枚举的所有其他情况。

更新:使用.NET Core,您现在可以使用.Append().Prepend()向可枚举的元素添加单个元素。优化实现以避免在幕后生成太多IEnumerator实现。

答案 3 :(得分:3)

4.7.1版的.NET Core和.NET Framework支持的新方法是使用Append扩展方法。

这将使您的代码简单而优雅

var sandwich = top.Append(filling).Union(bottom);