从C#中的Enumerable中准确获取x值的最佳方法是什么。
如果我像这样使用Enumerable .Take():

var myList = Enumerable.Range(0,10);
var result = myList.Take(20);

结果将只有10个元素。

我想用默认值填充缺少的条目。
像这样:
var myList = Enumerable.Range(0,10);
var result = myList.TakeOrDefault(20, default(int));  //Is there anything like this?

C#中是否有这样的功能,如果没有,实现此目的的最佳方法是什么?

最佳答案

您可以执行以下操作:

var result = myList.Concat(Enumerable.Repeat(default(int), 20)).Take(20);

并将其转换为扩展方法很容易:
public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> list, int count, T defaultValue)
{
    return  list.Concat(Enumerable.Repeat(defaultValue, count)).Take(count);
}

但是这里有一个微妙的陷阱。如果您的defaultValue不为null,则您多次添加同一对象,这对于值类型,对于引用类型来说将是完美的。可能是您不想要的。例如,如果您有:
var result = myList.TakeOrDefault(20, new Foo());

您将添加相同的Foo实例来填充您的集合。要解决该问题,您需要这样的事情:
public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> list, int count, Func<T> defaultFactory)
{
    return  list.Concat(Enumerable.Range(0, count).Select(i => defaultFactory())).Take(count);
}

您会这​​样称呼:
var result = myList.TakeOrDefault(20, () => new Foo())

当然,两种方法可以共存,因此您可以轻松拥有:
// pad a list of ints with zeroes
var intResult = myIntList.TakeOrDefault(20, default(int));
// pad a list of objects with null
var objNullResult = myObjList.TakeOrDefault(20, (object)null);
// pad a list of Foo with new (separate) instances of Foo
var objPadNewResult = myFooList.TakeOrDefault(20, () => new Foo());

09-29 21:30