将代理写为Func

时间:2012-06-27 19:37:01

标签: c# delegates lambda

这有效:

    //delegate
    Parallel.For(1023456789, 1033456789, delegate(long i)
            {
                if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
                if (IsPanDigital(i))
                {
                    list.Add(i);
                }
            }
        );

    //lambda expression
    Parallel.For(1023456789, 1033456789, i =>
            {
                if (i%10000000 == 0) Console.WriteLine("{0:N0}", i);
                if (IsPanDigital(i))
                {
                    list.Add(i);
                }
            }
        );

是否可以使用Func重写此逻辑?我在这里试过......不编译。

    var list = new List<long>();
    Parallel.For(1023456789, 1033456789, Blah(i, ref list));

public static Func<long> Blah(long i, ref List<long> list)
{
    if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
    if (IsPanDigital(i))
    {
        list.Add(i);
    }
}

我试图看看是否可以做到。

2 个答案:

答案 0 :(得分:7)

你几乎拥有它:

public static void Blah(long i, ref List<long> list)
{
    if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
    if (IsPanDigital(i))
    {
        list.Add(i);
    }
}

var list = new List<long>();
Parallel.For(1023456789, 1033456789, i => Blah(i, ref list));

(我将Blah的返回类型更改为void,并添加i =>以将其包装在lambda中,以便它可以匹配Action<long>

修改:或者将Blah更改为Action<long>并进行其他一些小的重构:

public static Action<long> Blah(List<long> list)
{
    return i =>
    {
        if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
        if (IsPanDigital(i))
        {
            list.Add(i);
        }
    };
}

var list = new List<long>();
Parallel.For(1023456789, 1033456789, Blah(list));

我认为第二个例子更接近你想要实现的目标。

正如@lee指出的那样,ref参数,至少在您显示的代码中是不需要的。 ref参数也不能在lambdas中使用,这会导致编译错误,所以我删除了它。如果您确实需要使用ref,请转到第一个示例。

您无法使用Func的原因是因为Func<T>返回T值,而Parallel正在寻找Action<T> ,返回void。

@dtb指出了一些非常重要的东西:“请注意,并行添加到多个线程的列表不是线程安全的。”您可以通过锁定list.Add方法锁定private static object来解决此问题。我猜你的绝大多数工作都在计算IsPanDigital,所以我认为这是有道理的。

答案 1 :(得分:1)

我不知道你想用它做什么,但你的功能应该是

  • 静态
  • void name(int i)

这里有一些编译

的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {

        static List<long> list = new List<long>();

        static void Main(string[] args)
        {


            //delegate
            Parallel.For(1023456789, 1033456789, delegate(long i)
            {
                if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
                if (IsPanDigital(i))
                {
                    list.Add(i);
                }
            });

            //lambda expression
            Parallel.For(1023456789, 1033456789, i =>
            {
                if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
                if (IsPanDigital(i))
                {
                    list.Add(i);
                }
            });

            Parallel.For(1023456789, 1033456789, Blah); //other overloads do accept other Actions

        }

        private static bool IsPanDigital(long i)
        {
            return false;
        }

        public static void Blah(int i) // = Action<int i>
        {
            if (i % 10000000 == 0) Console.WriteLine("{0:N0}", i);
            if (IsPanDigital(i))
            {
                list.Add(i);
            }
        }
    }
}