Как вернуть функцию делегата или лямбда-выражение в c #? - PullRequest
14 голосов
/ 28 апреля 2011

Я пытаюсь написать метод для возврата экземпляра самого себя. Псевдокод

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 ]

15 голосов
/ 28 апреля 2011

Вы можете сделать это так:

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;
}
3 голосов
/ 28 апреля 2011

Еще один способ сделать это - создать комбинатор .Легко peasy, но вы не можете сделать это с генериками из-за этого бесконечного регресса.Вы должны объявить это напрямую:

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 голосов
/ 28 апреля 2011

Это звучит очень похоже на итератор.Если вы можете изменить свой код на что-то вроде:

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

Где T - ваш тип ввода, а P - ваш тип результата.Не идентичен, но он должен выполнить работу.

Редактировать: Если вместо этого вам нужен свободный интерфейс, шаблон в значительной степени задуман как камень: вы создаете нестатический класс и возвращаете его из каждой функции (который не статичен) вы звоните.Нестатическая версия статического класса называется singleton , и вы можете использовать ее для этого шаблона.

1 голос
/ 28 апреля 2011

Я не уверен, что вы пытаетесь достичь, но как интеллектуальное упражнение "могу ли я вернуть метод, который возвращает себя?" следующие работы:

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

Как вы говорите, вы не можете заставить метод возвращать Func, поскольку это будет означать, что тип возвращаемого делегата должен быть Func, который возвращает Func, который возвращает Func и т. Д ...

Единственный выход из этого бесконечного отклика, который я вижу, - заставить его вернуть object вместо этого, что требует, чтобы вызывающая сторона приводила к правильному типу.

Редактировать: Ответ Porges лучше ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...