Почему я не могу определить Действие в строке в методе, ожидая делегата?

Учитывая следующий пример кода MSDN, почему не может, я определяю "встроенного" делегата Действия:

public static void Main(string[] args)
{
    Action someAction = () => Console.WriteLine("Hello from the thread pool!");

    Task.Factory.StartNew(someAction);
}

... таким образом "встраивают" как:

public static void Main(string[] args)
{
    Task.Factory.StartNew(Action someAction = () => Console.WriteLine("etc."));
}

Спасибо,

Scott

7
задан MPelletier 28 August 2010 в 01:41
поделиться

4 ответа

Это не правильный C#:

public static void Main(string[] args)
{
    Task.Factory.StartNew(Action someAction = () => Console.WriteLine("etc."));
}

Сделайте это вместо:

public static void Main(string[] args)
{
    Task.Factory.StartNew(() => Console.WriteLine("etc."));
}
13
ответ дан 6 December 2019 в 09:18
поделиться

Вы пытаетесь делегировать переменную в вызове метода. Простое удаление объявления переменной может быть в порядке:

public static void Main(string[] args)
{
    Task.Factory.StartNew(() => Console.WriteLine("etc."));
}

Здесь Action выводится не из самого лямбда-выражения, а из вызова метода, который оно пытается выполнить. Происходит обычное разрешение перегрузки, и компилятор пытается преобразовать лямбда-выражение к соответствующему типу параметра. Если бы тип параметра был просто Delegate (например, Control.Invoke), то вывод типа не удался бы, потому что у компилятора не было бы конкретных целевых типов, к которым можно было бы попытаться преобразовать.

Если это не сработает (я не могу легко проверить это сейчас), тогда вам просто нужно сделать каст, чтобы указать ему, к какому типу делегата должно быть преобразовано лямбда-выражение:

public static void Main(string[] args)
{
    Task.Factory.StartNew((Action)(() => Console.WriteLine("etc.")));
}

Честно говоря, в этот момент я бы предпочел видеть отдельную переменную с точки зрения удобства чтения.

4
ответ дан 6 December 2019 в 09:18
поделиться

Вы включаете заявление объявления, которое не является допустимым выражением. Попробуйте:

Task.Factory.StartNew(() => Console.WriteLine("etc."));

Если вы вызываете API, в котором тип делегата не может быть определен, вы можете использовать приведение или явно вызвать конструктор делегата:

Task.Factory.StartNew((Action)(() => Console.WriteLine("etc.")));
Task.Factory.StartNew(new Action(() => Console.WriteLine("etc.")));
2
ответ дан 6 December 2019 в 09:18
поделиться

Я бы не знал tbh, но думаю, вы можете:

public static void Main(string[] args)
{
    Task.Factory.StartNew(delegate() {Console.WriteLine("etc.");});
}
1
ответ дан 6 December 2019 в 09:18
поделиться