Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向IEnumerable追加或预加单个值的简单方法是什么<;T>;?_C#_Linq_Ienumerable - Fatal编程技术网

C# 向IEnumerable追加或预加单个值的简单方法是什么<;T>;?

C# 向IEnumerable追加或预加单个值的简单方法是什么<;T>;?,c#,linq,ienumerable,C#,Linq,Ienumerable,我需要在IEnumerable前面加一个值(在本例中,IEnumerable)。为此,我正在创建一个列表来包装第一个值,以便调用Concat: // get headers and data together IEnumerable<string[]> headers = new List<string[]> { GetHeaders() }; var all = headers.Concat(GetData()); //将标题和数据放在一起 IEnumerab

我需要在IEnumerable前面加一个值(在本例中,
IEnumerable
)。为此,我正在创建一个
列表
来包装第一个值,以便调用
Concat

// get headers and data together
IEnumerable<string[]> headers = new List<string[]> {
    GetHeaders()
};
var all = headers.Concat(GetData());
//将标题和数据放在一起
IEnumerable headers=新列表{
GetHeaders()
};
var all=headers.Concat(GetData());
恶心。有更好的办法吗?如何处理追加值的相反情况?

使用扩展方法。对于附加值而不是预加值,只需反向调用
Concat
。(即:
GetData().Concat(GetHeaders());

如果
GetHeaders()
返回单个字符串数组,我个人可能会将其包装在单个元素数组中,而不是列表中:

 var all = (new[] {GetHeaders()}).Concat(GetData());

为此,我编写了自定义扩展方法:

public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T item)
{
    foreach (T i in source)
        yield return i;

    yield return item;
}

public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, T item)
{
    yield return item;

    foreach (T i in source)
        yield return i;
}
正如chilltemp所评论的,这不会改变原始集合。以真正的Linq方式,它生成一个新的
IEnumerable


注意:建议对
源代码进行立即空参数检查,但为了简洁起见,未显示该检查。

Rx包含将值预先添加到序列的StartWith方法。还可以将返回值包装为序列,以便通过Concat追加

        var c = new[] {4};
        var c1 = c.StartWith(1, 2, 3);
        var c2 = c1.Concat(EnumerableEx.Return(5));

        c2.Run(Console.Write); // 12345

另一个选项是帮助器方法,用于从单个项创建序列:

public static class EnumerableExt
{
    public static IEnumerable<T> One<T>(T item)
    {
        yield return item;
    }
}

...
//prepend:
EnumerableExt.One( GetHeaders() ).Concat( GetData() );

//append:
GetData().Concat( EnumerableExt.One( GetHeaders() );
公共静态类EnumerableText
{
公共静态IEnumerable One(T项)
{
收益回报项目;
}
}
...
//预编:
EnumerableExt.One(GetHeaders()).Concat(GetData());
//附加:
GetData().Concat(EnumerableExt.One(GetHeaders());

对于.NET 4.7.1及更新版本来说,最简单、最干净的方法是使用无副作用且安全的方法

范例

// Creating an array of numbers
var numbers = new[] { 1, 2, 3 };

// Prepend and Append any value of the same type
var results = numbers.Prepend(0).Append(4);

// output is 0, 1, 2, 3, 4
Console.WriteLine(string.Join(", ", results ));

很好!我的库中有一些类似的。优雅。应该注意的是,这将通过枚举现有集合返回一个新的IEnumerable。它实际上不会附加/预附加原始集合。请注意,自从4.7.1.GetHeaders()返回
字符串[]
,GetData()以来,附加和预附加都内置在.NET中返回
IEnumerable
。你读了我的问题吗?@Gabe:这将适用于字符串[]和IEnumerable-数组实现IEnumerable。如果你的字符串[]但是,是字符串,事情有点不同。你的问题在这里不是非常清楚。@Gabe:我仍然不确定你到底想要什么-我做了另一次编辑,向你展示了如何将所有元素保留为数组…@Reed,我的评论是错误的-GetData()返回
IEnumerable
,很抱歉造成混淆。不过,您应该能够从我的问题中推断出类型。
// Creating an array of numbers
var numbers = new[] { 1, 2, 3 };

// Prepend and Append any value of the same type
var results = numbers.Prepend(0).Append(4);

// output is 0, 1, 2, 3, 4
Console.WriteLine(string.Join(", ", results ));