Local Functions, At It Again

I thought I got out everything during my rant about the new C# features, but apparently I missed something…

I was working on a WPF app for work and I used this to check if the code I wanted to execute could do so on the current thread (a common task in WPF development):

Action action = () =>
    {
        // do stuff
    };

if (Dispatcher.CurrentDispatcher.CheckAccess())
    action();
else
    Dispatcher.CurrentDispatcher.BeginInvoke(action);

Looks good.

Well Resharper, being the passive aggressive helper that it is, suggested that I convert the action variable to a local function, which resulted in this:

void Action()
{
    // do stuff
}

if (Dispatcher.CurrentDispatcher.CheckAccess())
    Action();
else
    Dispatcher.CurrentDispatcher.BeginInvoke((Action) Action);

Take a long look at that last line. Now, instead of creating an Action from a lambda expression, I have to cast a method to an Action. How is this better?!

Advertisements

3 thoughts on “Local Functions, At It Again

  1. I’m in a situation where coworkers love of Resharper has caused me to have to change up how I’ve done things. I’m not a fan of ‘var’; and unless I’m writing JavaScript, will likely never be a fan of it (despite all the pro-var arguments).

    The local functions feature seems completely ridiculous and unnecessary to me. And if a tool I was using started really pushing something like that, I’d (personally) consider shitcanning it.

    Like

  2. I think this is more down to BeginInvoke taking a Delegate rather than an Action. It’s worth noting that you can’t pass an inline lambda either without a cast, i.e. you have to do

    Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => { … }));

    If BeginInvoke took an Action then all three cases work without a cast. I tend to always use my own extension methods that take an Action when dealing with Invoke or BeginInvoke.

    Liked by 2 people

  3. As jdh28 says, the reason the cast with BeginInvoke is required is that BeginInvoke requires a Delegate parameter. BeginInvoke originates from the first async pattern available with .NET.
    With this scenario it’s really arguable to use local functions instead of the local lambda variable. However, there are many scenarios where local lambdas can be easily replaced by local functions without the need for a cast.
    See my article for local functions: https://csharp.christiannagel.com/2017/07/25/localfunctions/

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s