如何使用Func<>作为参数

时间:2016-08-10 05:07:10

标签: c#

我想使用Func作为参数委托param,如下所示:

delegate IPic Creator( Node pnode );
int CalSize( Creator c );
Func<Node,Ipic> funcCreator = ... ;
//then I want to use calSize
calsize( funcCreator ); // error
calsize( funcCreator.invoke ); // error

错误消息如下:

  

参数类型&#39; System.Func&lt; ... Node,... IPic&gt;&#39;不能分配给参数类型&#39; ...创作者&#39;。

因此,正如代码所示,我想使用Func作为参数。我该怎么办?

2 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点。

  1. 您可以定义执行funcCreator的委托并将其传递给函数:

    Creator cr = x => funcCreator(x); 
    CalSize(cr);
    

    相同
    CalSize(x => funcCreator(x));
    
  2. funcCreator

    创建代理
    CalSize(new Creator(funcCreator));
    
  3. 通过.Invoke方法:

    CalSize(funcCreator.Invoke);
    
  4. 至于我,我会考虑将方法定义更改为:

    int CalSize(Func<Node, IPic> c);
    

    使您更容易使用您的功能。
    我发现使用委托并没有用,现在根本不使用它们。当然,这只是我的观点和经验。如果您的项目成功使用了委托,那么您可以忽略这一部分:)

    效果

    对于性能测试,我修改了您的代码,以便Creator获得双倍并返回双倍(因为我没有NodeIPic)。

    我使用了以下代码:

    private static double lastResult;
    // lastResult is used so that calculation within methods is not optimized away
    
    public static void CalSize(Creator c)
    {
        lastResult = c(10.0); 
    }
    
    public static void CalSize2(Func<double, double> f)
    {
        lastResult = f(10.0);
    }
    
    static void Main()
    {
        Func<double, double> funcCreator = x => Math.Pow(x, 20);
    
        Stopwatch sw = new Stopwatch();
        sw.Start();
    
        for (int i = 0; i < 10000000; i++)
        {
            // measured code goes here
        }
    
        sw.Stop();
    }
    

    差异方法的结果如下:

    1. CalSize(x => funcCreator(x)); -> 579 ms
    2. CalSize(new Creator(funcCreator)); -> 625 ms
    3. CalSize(funcCreator.Invoke); -> 568 ms
    4. CalSize2(funcCreator); -> 467 ms
    

    因此,性能最低的方法是new Creator,因为构建委托需要一些时间。 第一种和第三种方法是相同的,因为它们实际上做同样的事情。 最高效的方法是Func函数参数之一,在我的答案结尾处描述了大约20%的优势。

    另外,请注意,需要10 000 000次操作才能产生~100 ms的差异。想象一下,你将要完成多少这些操作,而且很可能,你会明白这种差异是绝对无关紧要的。只需选择适合您的方法,不要关注性能。

答案 1 :(得分:1)

您需要将Func<>包装成代理人:

(Creator)(pnode => funcCreator(pnode))

有关详细信息,请参阅this answer