如何在c#中返回委托函数或lambda表达式?

时间:2011-04-28 04:50:43

标签: c# generics lambda

我正在尝试编写一个返回自身实例的方法。 伪代码是

Func<T,Func<T>> MyFunc<T>(T input)
{
    //do some work with input
    return MyFunc;
}

看起来很简单。但我在定义返回类型时遇到问题。 返回类型应该是委托

 which takes T as parameter, then returns a function 
 which takes T as parameter, then returns a function 
 which takes T as parameter, then returns a function

   ...recursive definition

我确信有一些我没有注意到的微妙之处。有人可以为我指出它吗? 谢谢。

4 个答案:

答案 0 :(得分:15)

你可以这样做:

delegate F<T> F<T>(T obj);

F<T> MyFunc<T>(T obj)
{
    return MyFunc;
}

但它几乎没用。你唯一能做的就是这样,这很奇怪:

void Main()
{
    MyFunc(1)(2)(3)(4);
}

delegate F<T> F<T>(T obj);

F<T> MyFunc<T>(T obj)
{
    Console.WriteLine(obj);
    return MyFunc;
}

答案 1 :(得分:3)

另一种方法是制作组合器。容易腻,但由于无限的退步,你不能用泛型做。你必须直接申报:

delegate D D(D d);

也就是说,D是一个代表,它接受一个D并返回一个D.

static D MyCombinator(D d)
{
    return MyCombinator;
}

关于C#中的组合器的更多想法:

http://blogs.msdn.com/b/ericlippert/archive/2006/06/23/standard-generic-delegate-types-part-two.aspx

答案 2 :(得分:2)

这听起来很像迭代器。如果您可以将代码重构为:

IEnumerator<P> GetEnumerator<T,P>(T input)
{
  while(<some condition>)
  {
     // do some work with input
     yield return results; 
  }
}

T是您的输入类型,P是您的结果类型。不完全相同,但它应该完成工作。

编辑:如果你想要一个流畅的界面,那么这个模式几乎是一成不变的:你创建了一个非静态类,并从你调用的每个函数(非静态函数)返回它。静态类的非静态版本称为 singleton ,您可以将其用于此模式。

答案 3 :(得分:1)

我不确定你想要达到的目标,但作为一项智力练习“我可以返回一种自我回归的方法吗?”以下作品:

object MyFunc<T>(T input)
{
    Func<T, object> returnValue = MyFunc;
    return returnValue;
}

就像你说的那样,你不能让方法返回Func,因为这意味着该委托的返回类型必须是Func,返回Func返回Func等...

我能看到的无限回归的唯一出路就是让它返回object,这要求调用者转换为正确的类型。

编辑: Porges答案更好......