Каков наиболее прямой способ преобразования лямбда-выражения или анонимной функции в объект делегата в C #? - PullRequest
0 голосов
/ 08 января 2011

Я пишу некоторый код для решения проблем с многопоточностью в системе, над которой я работаю, и один из рекомендуемых подходов заключается в использовании делегатов для решения проблем с многопоточностью. Но по какой-то причине мне не нравится определять делегата для каждой возможной операции, которую мне, возможно, придется перехватывать, и поэтому я предпочитаю работать с анонимными методами или лямбда-выражениями, но я компилятор отказывается преобразовывать любой из них в Систему. Делегировать объект.

Есть ли ярлык к этому?

if (someListBox.InvokeRequired)
{
someListBox.Invoke (Some_System.Delegate_Object, новый объект [] {item});
}
еще
someListBox.Items.Add (пункт);

Я хочу что-то вроде ...

if (someListBox.InvokeRequired)
{
someListBox.Invoke ((i) => {someListBox.Items.Add (i);}, новый объект [] {item});
}
еще
someListBox.Items.Add (пункт);

Ответы [ 2 ]

1 голос
/ 08 января 2011

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

private void AddItemToListView(ListViewItem item, ListView listView)
{
    if (listView.InvokeRequired)
    {
        listView.BeginInvoke((Action)delegate { AddItemToListView(item, listView); });
    }
    else
    {
        listView.Items.Add(item);
    }
}

Опять же, вы можете обсудить, как часто этот код выполняется.Если это не очень много, возможно, лучше немного упростить его, не проверяя InvokeRequired, а всегда оборачивая вызов в делегате, переданном в BeginInvoke:

private void AddItemToListView(ListViewItem item, ListView listView)
{
    listView.BeginInvoke((Action)delegate { listView.Items.Add(item); });       
}
1 голос
/ 08 января 2011

Одна из ваших проблем заключается в том, что компилятор не может определить типы параметров вашей лямды. И даже для данной сигнатуры параметра существует бесконечно много потенциальных типов делегатов. Так что вам нужно явно указать тип. Action<...> и Func<...> являются типичными кандидатами, если вас не интересуют имена параметров.

Я думаю, что это должно работать:

`someListBox.Invoke((Action<int>)((i) => {listviewResults.Items.Add(i); }), new object[] {item});`

Или в переработанном виде, чтобы избежать повторения:

Action<int> myAction=(i) => listviewResults.Items.Add(i);
if (someListBox.InvokeRequired)
{
    someListBox.Invoke( myAction, new object[] {item});
}
else
    myAction(item);

И я не вижу причин, по которым вы бы вообще хотели иметь i в качестве параметра:

Action myAction = () => listviewResults.Items.Add(item);
if (someListBox.InvokeRequired)
{
    someListBox.Invoke( myAction );
}
else
    myAction();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...