有没有办法在 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 并不是要重复函数调用;它旨在重复一个值。只需像任何理智的程序员一样使用循环;)。 我们也可以重复ActionAction 是一个值吗? @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,我只问了一个关于在不使用 ForForEach 或其他循环关键字的情况下重复函数的问题。你有什么想法吗?如果你不这样做,请不要评判我的知识! @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&lt;T&gt; 替换为 Func&lt;T,T&gt;

Enumerable.Repeat&lt;T&gt;(...) 方法的目的是创建一个包含 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# 的替代方案

C#开发的OpenRA的Enumerable.Concat方法应用

C#开发的OpenRA的Enumerable.Concat方法应用