您可以执行以下操作:
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
不为空,则您将多次添加同一个对象。这可能不是你想要的。例如,如果你有这个:
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());