每当我编写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();
但是这不会编译(出于显而易见的原因)。有人建议我如何创建我方便的花花公子功能?
答案 0 :(得分:2)
您需要一个类型约束来确保您可以实例化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);
答案 1 :(得分:2)
所以你最终只想要一个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;
}
答案 2 :(得分:0)
试试这样的事情:
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);
答案 3 :(得分:0)
您可以将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());
答案 4 :(得分:0)
我不确定您是否可以在没有任何反思的情况下管理您的问题
以下是一个小例子,您可以如何简单地使用泛型类型:
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();
}
我希望这能正确回答您的问题并符合您的需求