анонимные делегаты в C#

У «Большого масштаба C ++ Software Design» Джона Лакоса были инструменты, которые извлекали зависимости времени компиляции среди исходных файлов.

К сожалению, их хранилище на сайте Аддисона-Уэсли пропало (вместе с самим сайтом AW), но я нашел тарбол здесь: http://prdownloads.sourceforge.net/introspector/LSC-rpkg-0.1. tgz? download

Я нашел это полезным несколько работ назад, и он достоин того, чтобы быть свободным.

Кстати, если вы еще не читали книгу Лакоса, похоже, ваш проект принесет пользу. (Текущее издание немного устарело, но я слышал, что у Лакоса есть другая книга, выходящая в 2012 году.)

33
задан Lucas 10 June 2009 в 21:25
поделиться

6 ответов

Да. В .NET 3.5 вы можете использовать делегаты Func и Action . Делегаты Func возвращают значение, а делегаты Action возвращают void. Вот как будут выглядеть имена типов:

System.Func<TReturn> // (no arg, with return value)
System.Func<T, TReturn> // (1 arg, with return value)
System.Func<T1, T2, TReturn> // (2 arg, with return value)
System.Func<T1, T2, T3, TReturn> // (3 arg, with return value)
System.Func<T1, T2, T3, T4, TReturn> // (4 arg, with return value)

System.Action // (no arg, no return value)
System.Action<T> // (1 arg, no return value)
System.Action<T1, T2> // (2 arg, no return value)
System.Action<T1, T2, T3> // (3 arg, no return value)
System.Action<T1, T2, T3, T4> // (4 arg, no return value)

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

52
ответ дан 27 November 2019 в 17:40
поделиться

Вот делегат Action, который вы можете использовать, например:

private void RefreshForm()
{
    if (InvokeRequired) Invoke(new Action(Refresh));
    else Refresh();
}

Или с лямбда-синтаксисом:

private void RefreshForm()
{
    if (InvokeRequired) Invoke((Action)(() => Refresh()));
    else Refresh();
}

Наконец, есть синтаксис анонимного делегата:

private void RefreshForm()
{
    if (InvokeRequired) Invoke((Action)(delegate { Refresh(); }));
    else Refresh();
}
26
ответ дан 27 November 2019 в 17:40
поделиться

В этом конкретном случае вы можете (и должны) просто использовать MethodInvoker для этого ... вот почему он существует.

if (InvokeRequired)
    Invoke(new MethodInvoker(Refresh));
else
    Refresh();

Если бы вы делали что-то еще, вы могли бы, как ответили другие, использовать Func или Action , если они подходят вашему варианту использования.

8
ответ дан 27 November 2019 в 17:40
поделиться

Short version:

Invoke((MethodInvoker)delegate { Refresh(); });

Then you can also drop the check of InvokeRequired; you can just call it as it is. Works also if you need to pass parameters, so there is no need for other parameter-specific delegates (works just as well with the parameter-less Action delegate as well):

private void SetControlText(Control ctl, string text)
{
    Invoke((MethodInvoker)delegate { ctl.Text = text; });
}
4
ответ дан 27 November 2019 в 17:40
поделиться

Мне действительно нужен весь делегат специально для этого? не там какие-либо общие делегаты?

Определение ваших собственных делегатов действительно может облегчить отладку, хотя бы потому, что Intellisense может сообщить вам имена ваших параметров. Например, вы пишете делегат следующим образом:

public delegate int UpdateDelegate(int userID, string city, string, state, string zip);

Когда вы используете его код, .NET сообщит вам имена параметров, имя делегата и т. Д., Так что в определении делегата много контекста, если вы не точно знаете, как что-то используется.

Однако, если вы не возражаете пожертвовать Intellisense, уже существует класс делегатов, определенный в пространстве имен System, который может использоваться как специальные делегаты:

Func<T>
Func<T, U>
Func<T, U, V>
Func<T, U, V, W>
Action, Action<T>
Action<T, U>
Action<T, U, V>
Action<T, U, V, W>

Только Действие и Действие существует в .NET 2.0, но его достаточно просто объявить вспомогательный класс с остальными делегатами, которые вам нужны для такого рода различных специальных функций.

2
ответ дан 27 November 2019 в 17:40
поделиться

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

1
ответ дан 27 November 2019 в 17:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: