有没有办法在 C# 中使用 Enumerable.Repeat 方法重复 Func<T, T> ?
Posted
技术标签:
【中文标题】有没有办法在 C# 中使用 Enumerable.Repeat 方法重复 Func<T, T> ?【英文标题】:Is there any way to repeat a Func<T, T> with Enumerable.Repeat method in C#? 【发布时间】:2019-10-11 23:36:23 【问题描述】:我写了一个函数,它接受 (Func & int N) 并重复 Func N 次并返回结果。
public IEnumerable<T> MyFunction(Func<T, T> function, int iteration)
有没有办法使用 Enumerable.Repeat 重复一个函数?
public IEnumerable<T> MyFunction(Func<T, T> function, int iteration)
yield return Enumerable.Repeat<T>(function.Invoke(), iteration);
我尝试运行上面的代码,但函数运行了一次。
【问题讨论】:
一句话,没有。Repeat
并不是要重复函数调用;它旨在重复一个值。只需像任何理智的程序员一样使用循环;)。
我们也可以重复Action
。 Action
是一个值吗? @HereticMonkey
那不是执行动作;定义了 10 个准备被调用的动作(一个是,稍后,在你的ForEach
)(你也不应该需要ToList
)
Edit 您的问题以一种现实的方式使用它。现在看起来不太实用。循环会用更少的代码做同样的事情,这对以后的读者更有意义。..
你可以使用Repeat
构造一些奇怪的东西来重复一个函数,所以从技术上来说答案是肯定的。 Repeat
重复任何内容。但这会奇怪地令人费解。下一个开发人员会感到困惑,可能会使用循环重写它,然后担心会发生更复杂的事情而他们只是错过了它。然后,当他们意识到他们没有错过任何东西时,他们会有一种下沉的感觉,然后想,“哦,不,我还能在这里找到什么?”
【参考方案1】:
为什么不简单地循环调用方法:
for(int i = 0; i < iteration; i++)
yield return function(myTInstance);
或在 Linq 语句中:
return Enumerable.Range(0, iteration).Select(x => function(MyTInstance));
【讨论】:
谢谢,@HimBromBeere!但我正在寻找一种优雅的方式来重复一个函数。 @SalehBagheri 我没有得到你想要的。这段代码完全符合您的要求:多次执行一个方法并将所有方法的返回值聚合到一个集合中。 @HimBromBeere 我认为他应该了解什么是钉子,什么是工具,什么是返回类型,然后开始使用锤子 LINQ。否则他最终会脑子里一片混乱,成为“复制粘贴程序员”;)【参考方案2】:有一种方法,虽然我不确定它证明了什么。
static public IEnumerable<T> MyFunction<T>(Func<T> function, int iteration)
return Enumerable.Repeat(function, iteration).Select( x => x() );
public static void Main()
int n = 0;
foreach (var i in MyFunction(() => n++, 10)) Console.WriteLine(i);
出于某种原因,虽然看到人们这样做更常见:
return Enumerable.Range(0, iteration).Select( x => function() );
我一直在 *** 上看到后一种结构。
输出:
0
1
2
3
4
5
6
7
8
9
【讨论】:
@John-wu 您正在使用 LINQ 和 lambda 表达式来回答不懂枚举数和 yield 关键字的人提出的问题。没有 LINQ 和 lambda 的答案对于新手来说会更容易理解。 @Kamil,我只问了一个关于在不使用For
或 ForEach
或其他循环关键字的情况下重复函数的问题。你有什么想法吗?如果你不这样做,请不要评判我的知识!
@Kamil 我相信这个答案很有帮助,因为它展示了一个正确的、惯用的,并且可能是Enumerable.Repeat()
的唯一用途,即将它与 LINQ 结合以生成有用的序列。老实说,我不知道我还能用它做什么。【参考方案3】:
// this is wrong
public IEnumerable<T> MyFunction(Func<T, T> function, int iteration)
yield return Enumerable.Repeat<T>(function.Invoke(), iteration);
您在单个产量中返回由 Repeat(...) 返回的整个 IEnumerable 集合(毫无意义)。
您的方法的另一个问题是返回类型。如果要返回 Func 对象,则必须将方法的返回类型从 IEnumerable<T>
替换为 Func<T,T>
。
Enumerable.Repeat<T>(...)
方法的目的是创建一个包含 N 个给定对象实例的集合并返回整个集合。
如果你想在收益中返回对象,你必须一个一个地返回这些对象。
我认为你需要这样的东西: (为了更好地理解我没有使用 LINQ 和 lambda 表达式)
public Func<T,T> MyFunction(Func<T, T> function, int iteration)
// create a collection with `N = interation` items
IEnumerable<Func<T,T>> items = Enumerable.Repeat<T>(function.Invoke(), iteration);
// return items
foreach(Func<T,T> item in items)
yield return item;
【讨论】:
以上是关于有没有办法在 C# 中使用 Enumerable.Repeat 方法重复 Func<T, T> ?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Enumerable.Distinct() 中使用 lambda 表达式 [重复]
c# Enumerable中Aggregate和Join的使用
Java 8 流中的 LINQ Enumerable.Single() [重复]
Enumerable.First (System.Linq) C# 的替代方案