C# 如何将for(非foreach)循环转换为Linq?
假设我想要一个10个数字的序列,我有一个函数,可以根据需要生成数字:C# 如何将for(非foreach)循环转换为Linq?,c#,linq,for-loop,C#,Linq,For Loop,假设我想要一个10个数字的序列,我有一个函数,可以根据需要生成数字: var s = new List<int>(); for (var i=0; i<10; i++) { s.Add(Magically_generate_a_very_special_number()); } 这对我来说已经足够好了。但是,我需要先指定一个整数范围,这让我很烦恼——这是一个多余的步骤,因为我无论如何都会放弃这个值。是否可以执行以下操作 var s = Enumerable.Objec
var s = new List<int>();
for (var i=0; i<10; i++) {
s.Add(Magically_generate_a_very_special_number());
}
这对我来说已经足够好了。但是,我需要先指定一个整数范围,这让我很烦恼——这是一个多余的步骤,因为我无论如何都会放弃这个值。是否可以执行以下操作
var s = Enumerable.ObjectMaker(Magically_generate_a_very_special_number).Take(10);
似乎Enumerable.Repeat
几乎可以满足我的要求,但它会获取我给出的函数的结果,然后将其复制,而不是重复计算函数
顺便说一下,这个问题的灵感来自Math.NetIContinuousDistribution.Samples
方法。其主体如下所示:
while (true)
{
yield return Generate_a_random_number();
}
因此,您可以使用
myDistribution.samples.Take
从分布中获取样本序列。原则上,我可以编写自己的方法,以同样的方式生成迭代器,但我想知道是否已经存在迭代器。您可以尝试使用foreach方法:
Enumerable.Take(10).ToList().Foreach(Magically_generate_a_very_special_number);
缺点是你必须在两者之间做一个托利表
编辑误读的问题,以便nvmd:)您可以尝试使用foreach方法:
Enumerable.Take(10).ToList().Foreach(Magically_generate_a_very_special_number);
缺点是你必须在两者之间做一个托利表
编辑误读的问题,以便nvmd:)您可以创建一个由10个方法委托组成的序列,引用您的
神奇地生成一个非常特殊的\u编号
方法,然后连续调用它们
var s = Enumerable.Repeat<Func<int>>(generate, 10).Select(f => f());
var s=Enumerable.Repeat(generate,10)。选择(f=>f());
您可以创建一个由10个方法委托组成的序列,引用您的神奇地生成一个非常特殊的\u编号
方法,然后连续调用它们
var s = Enumerable.Repeat<Func<int>>(generate, 10).Select(f => f());
var s=Enumerable.Repeat(generate,10)。选择(f=>f());
我同意丹麦语的观点:我认为尝试在base linq中进行比在for循环中进行更丑陋、更难阅读。似乎违背了linq的目的
也就是说,也许你可以做一个扩展方法。只要你的神奇地生成一个非常特殊的编号
函数不需要参数,像这样的函数应该可以满足你的要求:
public static void Fill<T>(this IList<T> list, int repeat, Func<T> fn) {
for (int i = 0; i < repeat; i++) list.Add(fn());
}
我同意丹麦语的观点:我认为尝试在base linq中做比在for循环中做更丑陋、更难阅读。似乎违背了linq的目的 也就是说,也许你可以做一个扩展方法。只要你的
神奇地生成一个非常特殊的编号
函数不需要参数,像这样的函数应该可以满足你的要求:
public static void Fill<T>(this IList<T> list, int repeat, Func<T> fn) {
for (int i = 0; i < repeat; i++) list.Add(fn());
}
我们可以创建一个新方法,通过调用生成函数N次来生成N个对象,该函数遵循LINQ方法的一般模式,这样您就有了符合您确切需要的东西:
public static IEnumerable<T> Generate<T>(Func<T> generator, int count)
{
for (int i = 0; i < count; i++)
yield return generator();
}
我们可以创建一个新方法,通过调用生成函数N次来生成N个对象,该函数遵循LINQ方法的一般模式,这样您就有了符合您确切需要的东西:
public static IEnumerable<T> Generate<T>(Func<T> generator, int count)
{
for (int i = 0; i < count; i++)
yield return generator();
}
我不认为像您的
Enumerable.ObjectMaker
这样的东西是作为LINQ的方便部分存在的,但是您可以制作一个与之完全相同的东西
public static IEnumerable<T> ObjectMaker<T>(Func<T> generator) {
while (true)
yield return generator();
}
我不认为像您的
Enumerable.ObjectMaker
这样的东西是作为LINQ的方便部分存在的,但是您可以制作一个与之完全相同的东西
public static IEnumerable<T> ObjectMaker<T>(Func<T> generator) {
while (true)
yield return generator();
}
实际上,我指的是
foreach
循环,而不是foreach
方法。你的代码几乎就是我想要的。。。但是为什么我需要调用ToList
?@Superbest,因为扩展方法Foreach
是在List
上定义的,而不是IEnumerable
@VacheForeach
既不是扩展方法,也不是LINQ方法,尽管许多人相信这一点。这是一个可以追溯到.NET2.0的列表方法。@MatthewFerreira真的!谢谢你的更正,我会记住的。实际上我指的是foreach
循环,而不是foreach
方法。你的代码几乎就是我想要的。。。但是为什么我需要调用ToList
?@Superbest,因为扩展方法Foreach
是在List
上定义的,而不是IEnumerable
@VacheForeach
既不是扩展方法,也不是LINQ方法,尽管许多人相信这一点。这是一个可以追溯到.NET2.0的列表方法。@MatthewFerreira真的!感谢您的更正,我会记住这一点。我可能真的有点过分了,但无论如何,LINQ的目的是减少代码行数,并根据特定的条件从枚举中选择特定的元素。它并不是真的要创建新对象。不,这是一个完全合理的评论。然而,对我来说,在某些情况下,LINQ更容易阅读(在我自己的个人项目中)。我在这里可能真的有点过分,但IMHO,LINQ的目的是减少代码行数,并根据特定条件或不特定条件从枚举中选择特定元素。它并不是真的要创建新对象。不,这是一个完全合理的评论。然而,对我来说,在某些情况下,LINQ更容易阅读(在我自己的个人项目中)。