Reputation: 3155
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
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
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
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
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