开发者

What is the most direct way of transforming a lambda expression or anonymous function into a Delegate Object in C#?

开发者 https://www.devze.com 2023-02-03 08:54 出处:网络
I am writing some code to solve thread-safe issues in a system am working on, and one of the recommended approaches is to use delegates to solve cros开发者_StackOverflow中文版s-thread issues. But for

I am writing some code to solve thread-safe issues in a system am working on, and one of the recommended approaches is to use delegates to solve cros开发者_StackOverflow中文版s-thread issues. But for some reason, I don't like having to define a delegate for every possible operation i might have to intercept, and thus prefer working with anonymous methods or lambda expressions, but I the compiler refuses to cast any of these to a System.Delegate object.

Is there a shortcut to this?

if (someListBox.InvokeRequired)

{

someListBox.Invoke(Some_System.Delegate_Object, new object[] {item});

}

else

someListBox.Items.Add(item);

I want something like...

if (someListBox.InvokeRequired)

{

someListBox.Invoke((i) => { someListBox.Items.Add(i); }, new object[] {item});

}

else

someListBox.Items.Add(item);


One of your problems is that the compiler can't infer the parameter types of your lamda. And even for a given parameter signature there are infinitely many potential delegate types. So you need to explicitly give a type. Action<...> and Func<...> are typical candidates if you don't care about parameter names.

I think this should work:

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

Or in refactored form to avoid repeating yourself:

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

And I see no reason why you'd want to have i as a parameter at all:

Action myAction = () => listviewResults.Items.Add(item);
if (someListBox.InvokeRequired)
{
    someListBox.Invoke( myAction );
}
else
    myAction();


The downside with the approach that you want is that the actual work will be implemented in two places. One alternative approach might look like this:

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

Then again, you could debate how often this code is executed. If it is not extremely much, perhaps its better to simplify it a bit by not checking for InvokeRequired, but rather always wrap the call in a delegate passed to BeginInvoke:

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

精彩评论

暂无评论...
验证码 换一张
取 消