【问题标题】:C#: Recursive functions with LambdasC#:使用 Lambda 的递归函数
【发布时间】:2010-11-07 22:15:44
【问题描述】:

以下不编译:

Func<int, int> fac = n => (n <= 1) ? 1 : n * fac(n - 1);

局部变量 'fac' 可能不是 访问前初始化

如何使用 lambdas 创建递归函数?

[更新]

这里还有两个我觉得有趣的链接:

  1. Eric Lippert's "Why does a recursive lambda cause a definite assignment error?"
  2. Anonymous Recursion in C#

【问题讨论】:

  • 你真的想要吗?对于可维护性和理解性而言,这看起来像是一场噩梦......

标签: c# recursion lambda factorial


【解决方案1】:

C# 不支持这种特殊风格的函数作为单行声明。您必须将声明和定义分成两行

Func<int, int> fac = null;
fac = n => (n <= 1) ? 1 : n * fac(n - 1);

【讨论】:

    【解决方案2】:

    天哪,如果您刚刚输入“为什么递归 lambda 会导致明确的赋值错误?”进入一些搜索引擎,你会在我关于这个主题的文章中找到答案。

    :-)

    http://blogs.msdn.com/ericlippert/archive/2006/08/18/why-does-a-recursive-lambda-cause-a-definite-assignment-error.aspx

    【讨论】:

    • +1 for '如果您刚刚输入“为什么递归 lambda 会导致明确的赋值错误?”进入一些搜索引擎':-)
    【解决方案3】:

    您必须先创建fac,然后再分配它(这很不实用,因为它依赖于多个分配)或使用所谓的Y-combinators

    例子:

    delegate Func<TIn, TOut> FixedPointFunction<TIn, TOut>(Func<TIn, TOut> f);
    
    static Func<T, TRes> Fix<T, TRes>(FixedPointFunction<T, TRes> f) {
        return f(x => Fix(f)(x));
    }
    
    static void Main(string[] args) {
    
        var fact = Fix<int, int>(f => x => (x <= 1) ? x : x * f(x - 1));
    
        Console.WriteLine(fact(5));            
    }
    

    但请注意,这可能有点难以阅读/理解。

    【讨论】:

      【解决方案4】:

      从 c# 7.0 开始,您终于可以在一行中使用local function

      int fac(int n) => (n <= 1) ? 1 : n * fac(n - 1);
      

      【讨论】:

      猜你喜欢
      • 2013-08-07
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-26
      相关资源
      最近更新 更多