每当我编写 C# 时,我都会使用 Linq,因为我喜欢它,它让我像函数式程序员一样思考,我经常发现这比命令式编程容易得多。创建对象随机列表时,我经常使用的约定如下:
var animals= Enumerable.Range(0, 100).Select(n => new Animal()).ToList();
我知道这是(可能更慢的(合成糖,用于将项目添加到列表中的 for 循环。这对我来说是完全可以接受的,因为它不会冒犯我的理智者。这是我不喜欢的:
var animals= Enumerable.Range(0, 100(.选择(n => new Animal(((。ToList((;
我想制作一个帮助程序 Func,它以更少的打字来做到这一点。理想情况下,我想输入:
var animals = NewRange(0, 100, Animal);
但是我正在为如何做到这一点而烦恼(如果可能的话(。我可以使用反射和各种其他粗俗的东西(哎呀!(,但没有这些,我就无法弄清楚。这是我得到的最接近的:
public Func<int, Type, List<object>> NewRange = (n, t) => Enumerable.Range(0, n).Select(o => new t()).ToList();
但这不会编译(出于显而易见的原因(。有人对我如何创建我的方便花花公子功能有一些建议吗?
所以你最终只想要一个 IEnumerable,用 n 个实例初始化,全部使用默认构造函数?
像这样的事情呢:
public static List<T> CreateList<T>(int numberOfItems) where T : new()
{
var result = new List<T>(numberOfItems);
for (int ix = 0; ix < numberOfItems; ix++)
{
result.Add(new T());
}
return result;
}
你需要一个类型约束来确保你可以实例化T
,所以:
List<T> NewRange<T>(int howMany) where T : new()
{
return Enumerable.Range(0, howMany).Select(n => new T()).ToList();
}
您可以像这样使用它:
var animals = NewRange<Animal>(100);
您可以将 lambda 传递给函数以创建新对象:
public static List<T> NewRange<T>(int n, Func<T> NewObject) {
return Enumerable.Range(0, n).Select(_ => NewObject()).ToList();
}
然后这样称呼它:
var Animals = NewRange(10, () => new Animal());
试试这样的事情:
public static List<T> NewRange<T>(int n) where T: new()
{
return Enumerable.Range(0, n).Select(_ => new T()).ToList();
}
或与表情体成员:
public static List<T> NewRange<T>(int n) where T : new() =>
Enumerable.Range(0, n).Select(_ => new T()).ToList();
并使用它:
var animals = NewRange<Animal>(100);
我不确定您是否可以在没有任何反射的情况下管理您的问题
下面是一个小示例,如何简单地使用泛型类型进行操作:
public void Main()
{
var animals = NewRange<Animal>(0, 100);
}
public static List<T> NewRange<T>(int n, int b)
{
return (List<T>)Enumerable.Range(n, b).Select(instance => (T)Activator.CreateInstance(typeof(T))).ToList();
}
我希望这能正确回答您的问题并满足您的需求