Wei Ma
Wei Ma

Reputation: 3155

How do I return a delegate function or a lambda expression in c#?

I am trying to write a method to return an instance of itself. The pseudo code is

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

seems simple enough. But I am having problem defining the return type. The return type should be a delegate

 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

I am sure there was some subtle thing that I didn't notice. Can someone point it out for me? Thank you.

Upvotes: 14

Views: 5746

Answers (4)

Eric Lippert
Eric Lippert

Reputation: 660058

Another way to do it is to make a combinator. Easy peasy, but you can't do it with generics because of that infinite regress. You've got to declare it directly:

delegate D D(D d);

That is, D is a delegate that takes a D and returns a D.

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

A few more thoughts on combinators in C# here:

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

Upvotes: 3

Justin
Justin

Reputation: 86729

I'm not sure what you are trying to achieve, but as an intelectual exercise "can I return a method that returns itself?" the following works:

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

Like you say, you can't have the method return a Func as this would mean the return type of that delegate would need to be a Func that returns a Func that returns a Func etc...

The only way out of this infinite recusion that I can see is to have it return an object instead, which requires that the caller cast to the correct type.

Edit: Porges answer is better...

Upvotes: 1

porges
porges

Reputation: 30580

You can do it like this:

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

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

But it's pretty much useless. The only thing you can really do is something like this, which is weird:

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;
}

Upvotes: 15

Blindy
Blindy

Reputation: 67380

This sounds a lot like an iterator. If you can refactor your code to be something like:

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

Where T is your input type and P is your result type. Not identical, but it should get the work done.

Edit: If instead you want a fluent interface, the pattern is pretty much set in stone: you create a non-static class and return it from every function (which isn't static) you call. The non-static version of a static class is called a singleton and you can use it for this pattern.

Upvotes: 1

Related Questions