Linq递归用法(摘录)

.net framework 3.5 有了Linq使得对委托有了更多的支持,下面让我们来看几个有趣的示例.通常情况下,我们实现一个递归算法要写

一个函数,同时还有调用的几行代码.

  现在来看使用Linq的如何实现简洁的代码,代码如下:

using System;
     using System.Collections.Generic;
    using System.Linq;
     using System.Text;
     using System.IO;
    using NUnit.Framework;
   
    namespace WindowsFormsApplication1
    {
        /// <summary>
        /// TestRecursionWithLINQ
        /// </summary>
        /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com/ </remark>
        [TestFixture]
        public class TestRecursionWithLINQ
        {
   
            /// <summary>
            /// Factorials this instance.
            /// </summary>
            /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com/ </remark>
            [Test]
            public void Factorial()
            {
                Func<int, int> fib = null;
                fib = n => (n == 1) ? 1 : fib(n - 1) * n;
                Console.WriteLine(fib(5));
            }
   
            /// <summary>
            /// Fibonaccis this instance.
            /// </summary>
            /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com/ </remark>
            [Test]
            public void Fibonacci()
            {
                Func<int, int> fib = null;
                fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;
                Console.WriteLine(fib(6));
            }
   
   
            /// <summary>
            /// Recursions the get files.
            /// </summary>
            /// <remark>Author : PetterLiu 2009-03-29 11:27  http://wintersun.cnblogs.com/ </remark>
            [Test]
            public void RecursionGetFiles()
            {
                var RecGetFiles =
                    Functional.Y<string, IEnumerable<string>>
                    (f => d => Directory.GetFiles(d).Concat(Directory.GetDirectories(d).SelectMany(f)));
   
                foreach (var f in RecGetFiles(Directory.GetCurrentDirectory()))
                    Console.WriteLine(f);
   
            }
   
            /// <summary>
            /// Factorial2s this instance.
            /// </summary>
            /// <remark>Author : PetterLiu 2009-03-29 11:28  http://wintersun.cnblogs.com/ </remark>
            [Test]
            public void Factorial2()
            {
                var dd = Functional.Y<int, int>(h => m => (m == 1) ? 1 : h(m - 1) * m);
                Console.WriteLine(dd(5));
            }
        }
   
        /// <summary>
        /// Functional
        /// </summary>
        /// <remark>Author : Wes Dyer</remark>
        public class Functional
        {
            /// <summary>
            ///delegate  Func<A, R>
            /// </summary>
            private delegate Func<A, R> Recursive<A, R>(Recursive<A, R> r);
            /// <summary>
            /// Ys the specified f.
            /// </summary>
            /// <typeparam name="A"></typeparam>
            /// <typeparam name="R"></typeparam>
            /// <param name="f">The f.</param>
            /// <returns></returns>
            public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
            {
                Recursive<A, R> rec = r => a => f(r(r))(a);
                return rec(rec);
            }
        }
    }

Factorial是阶乘,接着是Fibonacci数列.之后把这个定义为一个名叫Funcional类,其中包含一个static方法.Factorial2使用这个类

再实现阶乘,是不是简单的多.接着是RecursionGetFiles一个实际的应用,递归遍历文件夹取得文件名列表.像树型结构算法都可以用

它来实现,是不是很有趣?

其中几个关键方法可以参考:
Func<(Of <(T, TResult>)>) 委托
封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。
Enumerable.SelectMany<(Of <(TSource, TResult>)>) 方法 (IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, IEnumerable<

(Of <(TResult>)>)>)>))
将序列的每个元素投影到 IEnumerable<(Of <(T>)>) 并将结果序列合并为一个序列。
Enumerable.Concat<(Of <(TSource>)>) 方法
连接两个序列。


Action<int, int, int> Fibonacci_A = (firstNum, secondNum, boundNum) =>
{
               int exchangeNum = firstNum + secondNum;
               firstNum = secondNum;
               secondNum = exchangeNum ;

               if (secondNum > boundNum)
               {
                   return;
               }
               else
           {
                   Console.WriteLine(exchangeNum );
                   MethodBase.GetCurrentMethod().Invoke(null, new object[] { firstNum, secondNum ,boundNum});
               }
           };

   Fibonacci_A(0,1,200);
           Func<int,int> Fibonacci_B = n =>
       {
                   if ((n == 0) || (n == 1))
                   {
                       return 1;
                   }
                   return (Convert.ToInt32(MethodBase.GetCurrentMethod().Invoke(null, new object[] { n - 2 }))
                       +Convert.ToInt32(MethodBase.GetCurrentMethod().Invoke(null, new object[] { n - 1 })));
               };

           for (int i = 0; i < 10; i++)
           {
               Console.WriteLine(Fibonacci_B(i));
           }为了实现委托自身的递归调用两个函数都通过反射来实现。

原文地址:https://www.cnblogs.com/Yjianyong/p/2267802.html