假设您将列表定义为:
List<string> list1 = new List<string>{"Cat","Dog","Bird","Badger"};
现在,假设您想编写一个可以获取该列表并更改其长度的通用函数。因此,如果您减去长度以使列表变小,则会截断列表中的项目,或者如果长度较长,则会复制List的内容,然后向其添加新的附加索引。 / p>
更大的长度参数将导致:
List<string> list1 = new List<string>{"Cat","Dog","Bird","Badger","","","","",""};
虽然较小的长度会导致:
List<string> list1 = new List<string>{"Cat","Dog"};
假设不需要进行深度复制,那么如何编写这样的函数?
答案 0 :(得分:4)
您可以使用AddRange
和RemoveRange
,这比使用Add
和/或RemoveAt
循环更好:
public static void PaddedResize<T>(
List<T> list,
int size,
T padding = default(T)
) {
// Compute difference between actual size and desired size
var deltaSize = list.Count - size;
if (deltaSize < 0) {
// If the list is smaller than target size, fill with `padding`
list.AddRange(Enumerable.Repeat(padding, -deltaSize));
} else {
// If the list is larger than target size, remove end of list
list.RemoveRange(size, deltaSize);
}
}
这适用于不可变,引用透明或结构类型,但对于花园种类,它会反复使用相同的元素填充列表,这可能是不理想的。要解决此问题,请使用创建填充的工厂函数:
public static void PaddedResize<T>(
List<T> list,
int size,
Func<T> paddingFactory // Changed parameter to a factory function
) {
// Compute difference between actual size and desired size
var deltaSize = list.Count - size;
if (deltaSize < 0) {
// If the list is smaller than target size, fill with the result of calling `paddingFactory` for each new item
list.AddRange(Enumerable.Repeat(0, -deltaSize).Select(_ => paddingFactory()));
} else {
// If the list is larger than target size, remove end of list
list.RemoveRange(size, deltaSize);
}
}
答案 1 :(得分:-2)
您可能想要创建一些ListUtils
类并在那里编写静态泛型函数。如果您想要一个包含所需项目的新列表
static class Listutils
{
public static List<T> Shrink<T>(List<T> src, Predicate<T> predicate)
{
if (src == null || src.Count == 0)
return null;
List<T> newList = new List<T>();
foreach(T item in src)
{
if (predicate(item))
newList.Add(item);
}
return newList;
}
}
........somewhere in your program
List<string> list = new List<string>{"Cat","Dog","Bird","Badger","Snake"};
// select only Cat, Dog and Bird
List<string> shrinked = ListUtils.Shrink(list, (name) => delegate
{
return (name == "Cat" || name == "Dog" || name == "Bird");
});