Проблема объявления рекурсивного делегата в C # - PullRequest
1 голос
/ 05 июля 2010

* ПОЖАЛУЙСТА, СМ. КОНЕЦ ДЛЯ ВАЖНОГО РЕДАКТИРОВАНИЯ *

По различным причинам у меня есть что-то вроде:

delegate void Task(QueueTask queueTask); delegate void QueueTask(Task task);

Использование Visual Studio Express2008 это работает более или менее хорошо, за исключением лямбда-выражений, которые не могут быть выведены, если я попытаюсь вызвать и вызвать queueTask () в функции без явной помощи:

void MyTask(QueueTask queueTask)
{
   queueTask(qt => {}); // fails with queueTask doesn't take 1 parameter?
}

Это работает, хотя:

void MyTask(QueueTask queueTask)
{
   queueTask((QueueTask qt) => {});
}

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

Спасибо.

* ВАЖНОЕ РЕДАКТИРОВАНИЕ НИЖЕ *

Кажется, только если я помещаю класс TaskPool2 в отдельную сборку, я получаю ошибку компиляции !?

namespace Test
{
    public class TaskPool2
    {
        public delegate void QueueTask(Task task);
        public delegate void Task(QueueTask queueTask);


        public void Queue(Task task) { }
    }
}


namespace MyApp
{
    class Program
    {
        static void SomeFunc()
        {
            Test.TaskPool2 taskPool = new Test.TaskPool2();


            taskPool.Queue(queue => { Console.WriteLine("A"); queue(q => Console.WriteLine("C")); });
        }
    }
}

Да, это несколько запутанно!

Ответы [ 2 ]

1 голос
/ 17 октября 2010

После использования нескольких способов взломать \ исправить код я обнаружил небольшую информацию.

Когда компилятор достигает строки

taskPool.Queue(queue => { Console.WriteLine("A"); queue(q => Console.WriteLine("C")); });

он упадет компиляцией, если (и я думаю, только если) он никогда не сталкивался с QueueTask раньше. Например, объявление следующей строки в классе (до или после метода SomeFunc)

Public Delegate Test.TaskPool2.QueueTask x;

исправит компиляцию. Кроме того, добавление следующей строки над строкой errornouse также исправит это

Test.TaskPool2.QueueTask x; // declare x to be QueueTask

Я перепробовал еще несколько строк, используя QueueTask, и они сработали (исправьте компиляцию).

Я могу только предположить, что компилятор не загружает определение для QueueTask, и это приводит к этой странности.

Кажется, даже как ошибка.

Надеюсь, мне удалось это хорошо объяснить.

0 голосов
/ 05 июля 2010

(Это был бы комментарий, но на самом деле невозможно дать полный код в комментариях.)

Ваш код уже работает как есть:

delegate void Task(QueueTask queueTask);
delegate void QueueTask(Task task);

class Test
{
    void MyTask(QueueTask queueTask)
    {
        queueTask(qt => {}); // fails with queueTask doesn't take 1 parameter?
    }
}

Компилируется без проблем.

Пожалуйста, создайте такую ​​же короткую, но полную программу, которая не компилируется.

...