Showing posts with label Action. Show all posts
Showing posts with label Action. Show all posts

Tuesday, November 5, 2013

Tricky LINQ ToDictionary Where Action is the Value

This is going to be a quick one, but something I wanted to jot down before I forgot it. I needed a Dictionary<MyEnum, Action> and figured I would use LINQ's awesome ToDictionary<,>() method. I've used this plenty of times before and so I figured this would be a snap:

    private readonly Dictionary<MyEnum, Action> _actions;

    public Keyboard()
    {
        _actions = Enum.GetValues(typeof(MyEnum))
                       .Cast<MyEnum>()
                       .ToDictionary(x => x, x => () => { });
    }

Feeling good about my awesome LINQ statement, I went to move on when I noticed that my precious had red squigglies under it. Ah, probably just a typo or something. I mean, I am susceptible to those sometimes, I suppose. Upon further inspection, it was not a typo but a fun little error:

Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer<Foo.Bar.MyEnum>' because it is not a delegate type

Even more fun, this method was insisting I was trying to create a Dictionary<MyEnum, MyEnum>. No I'm not! What the heck!

Just Breathe...

Ah yes, it is easy to forget that there are four overloads for ToDictionary. Three of which are ToDictionary<TSource, TKey>, all of which an Action perfectly conflicts, and fourth which is ToDictionary<TSource, TKey, TElement>. So, my implementation, above, caused the compiler to become confused since it thought I was trying to pull off passing in an Action as an IEqualityComparer. So, we need to force the compiler to pick the last overload by specifying all the Ts:

        _actions = Enum.GetValues(typeof(MyEnum))
                       .Cast<MyEnum>()
                       .ToDictionary<MyEnum, MyEnum, Action>(x => x, x => () => { });

Simple really.

Sunday, July 21, 2013

Fun With IDisposable and Action

IDisposable is a pretty neat tool in the .NET framework. For those that don't know what it is, a class that implements IDisposable can be wrapped in a using statement. When the code exits the block created by the using statement, the object's Dispose method is guaranteed to be called, automatically. (This includes the block being exited because of an exception.)

Every now and then I need to create some Razor extension methods (especially to avoid re-typing HTML wrappers around articles, or what-not). If you use Razor with ASP.NET MVC, you are probably familiar with Html.BeginForm(). It allows us to wrap an HTML form and emits the form's opening and closing tags around our elements.

@model MyNameSpace.MyModel
@using (Html.BeginForm())
{
    @Html.TextBoxFor(x => x.SomeProperty)
}

While I won't get into specifics of what extensions I have created in the past in this post, I wanted to discuss a way of cleaning up our code if we have a bunch of these extensions. Let's say we have two extension methods that make use of IDisposable. I have seen—and written myself—a few implementations like the following.

public static class HtmlHelperExtensions
{
    public static FooCloser Foo(this HtmlHelper helper)
    {
        // Do work
        return new FooCloser(helper);
    }

    public static void CloseFoo(this HtmlHelper helper)
    {
        // Finish up
    }

    public static BarCloser Bar(this HtmlHelper helper)
    {
        // Do work
        return new BarCloser(helper);
    }

    public static void CloseBar(this HtmlHelper helper)
    {
        // Finish up
    }
}

public class FooCloser : IDisposable
{
    private readonly HtmlHelper _helper;

    public void Dispose ()
    {
        _helper.CloseFoo();
    }

    public FooCloser (HtmlHelper helper)
    {
        _helper = helper;
    }
}

public class BarCloser : IDisposable
{
    private readonly HtmlHelper _helper;

    public void Dispose ()
    {
        _helper.CloseBar();
    }

    public BarCloser (HtmlHelper helper)
    {
        _helper = helper;
    }
}

After a while, all those "Closer" classes build up. But, there is a pattern that emerges that we can take advantage of. Instead of each set of helper methods getting their own IDisposable "closer," we can merge them all into one and refactor our code a bit by making use of Action.

public static class HtmlHelperExtensions
{
    public static IDisposable Foo(this HtmlHelper helper)
    {
        // Do work
        return new Closer(helper.CloseFoo);
    }

    public static void CloseFoo(this HtmlHelper helper)
    {
        // Finish up
    }

    public static IDisposable Bar(this HtmlHelper helper)
    {
        // Do work
        return new Closer(helper.CloseBar);
    }

    public static void CloseBar(this HtmlHelper helper)
    {
        // Finish up
    }
}

public class Closer : IDisposable
{
    private readonly Action _action;

    public void Dispose ()
    {
        _action();
    }

    public Closer (Action action)
    {
        _action = action;
    }
}

Now we have one universal "closer" that we can use anywhere we want to return an IDisposable to use this little trick—and not just with Razor extensions.