Почему я не могу определить Action в строке в методе, ожидающем делегата? - PullRequest
7 голосов
/ 05 июля 2010

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

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

    Task.Factory.StartNew(someAction);
}

... так что "inline" вроде:

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

Спасибо,

Скотт

Ответы [ 4 ]

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

Это недопустимо 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."));
}
4 голосов
/ 05 июля 2010

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

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.")));
}

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

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

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

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

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

Task.Factory.StartNew((Action)(() => Console.WriteLine("etc.")));
Task.Factory.StartNew(new Action(() => Console.WriteLine("etc.")));
1 голос
/ 05 июля 2010

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

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