I have moved!

I've moved my blog
CLICK HERE
Showing posts with label LINQ. Show all posts
Showing posts with label LINQ. Show all posts

Monday, 26 January 2009

Linq to C++0x

Updated 2009-01-28 - completely different approach to get a fluent interface.

Updated 2009-05-22 - See new post with decltype goodness!

C++ has long had some functional-styled things in its standard library, in particular a header file called <functional>. But actually using it in a functional way has been painful, largely due to the lack of lambdas.

But C++0x (very good Wikipedia page, by the way) solves this, amongst many other long-standing problems.

With lambdas in place, the next thing I naturally wonder is: what about a complete system of lazy-evaluated list processing, which is to say: what about Linq to Objects in C++?

The C++ equivalent of IEnumerable<T> is a collection of T. Another good thing in C++0x is concepts, which allows us to state for the first time precisely what we mean by a collection in C++. I don't yet have a compiler that supports concepts, so I'll just say that for the sake of argument, a collection is anything that has a nested type called const_iterator and two const methods called begin and end that return instances of that const_iterator type. (I'm using const iterators because I want to support functional style programming, and support for immutability is one area where C++ still leaves C# in the dust).

The iterator is the equivalent of IEnumerator<T>, and must have an * operator so we can retrieve the current item, and a ++ operator so we can navigate to the next item. We discover if we're at the end by comparing the iterator with the instance returned by end, so iterators must also have equality comparison.

Just as a minimal demonstration, I want to recreate the Select and Where extension methods. They don't actually use any new C++0x features, but as we'll see, they become much more pleasant to use as a result of lambdas.

In order to share as much code as I can, I'll create a single new container-like class template called filter, which simulates a container by borrowing the contents of another container. It will have built-in features to support skipping over some elements, and to transform elements to new values (not necessarily of the same type).

Because of this approach, I'll need a way to switch off these features when I don't need them. When deciding whether to skip over an element, we will use a predicate, which is a function that takes some value and returns a bool. To switch off that feature, we'd simply pass a predicate that always returns true:

template <class T>
struct always_true
{
    bool operator() (const T &) const { return true; }
};

Similarly to switch off element transformation we need a function that just passes through whatever it is given:

template <class T>
struct pass_thru
{
    T operator() (const T &e) const { return e; }
};

I could of course re-write these simple functions as lambdas wherever I need them, but as I need them in a couple of places it makes sense to name them in the traditional way.

And now here's the filter class template.

template <class TElemFrom, 
          class TElemTo, 
          class TIterFrom, 
          class TSelector,
          class TPredicate>
class filter
{
    TIterFrom from_;
    TIterFrom end_;
    const TSelector &selector_;
    const TPredicate &predicate_;

public:
    filter(TIterFrom from, TIterFrom end, 
             const TSelector &selector, 
             const TPredicate &predicate)
        : from_(from), end_(end), 
          selector_(selector), 
          predicate_(predicate) {}

    class const_iterator
    {
        TIterFrom from_;
        TIterFrom end_;
        const TSelector &selector_;
        const TPredicate &predicate_;

        void locate()
        {
            while (!done())
            {
                if (predicate_(*from_))
                    return;

                ++from_;
            }
        }

        bool done() const { return (from_ == end_); }

    public:
        const_iterator(TIterFrom from, TIterFrom end, 
                       const TSelector &selector,
                       const TPredicate &predicate)
            : from_(from), end_(end), 
              selector_(selector),
              predicate_(predicate) { locate(); }

        TElemTo operator*() const { return selector_(*from_); }

        const_iterator operator++()
        {
            ++from_;
            locate();
            return *this;
        }

        bool operator==(const const_iterator &other) const
            { return done() && other.done(); }

        bool operator!=(const const_iterator &other) const
            { return !done() || !other.done(); }
    };

    typedef TElemFrom value_type;

    const_iterator begin() const 
        { return const_iterator(from_, end_, selector_, predicate_); }

    const_iterator end() const 
        { return const_iterator(end_, end_, selector_, predicate_); }

    template <class TElemTo2, class TSelector>
    filter<TElemTo, 
             TElemTo2,
             const_iterator, 
             TSelector,
             always_true<TElemTo> >
        select(const TSelector &selector)
    {
        return filter<TElemTo, 
                        TElemTo2, 
                        const_iterator, 
                        TSelector, 
                        always_true<TElemTo> >
                    (begin(), 
                     end(), 
                     selector, 
                     always_true<TElemTo>());
    }

    template <class TPredicate>
    filter<TElemTo, 
              TElemTo,
             const_iterator, 
             pass_thru<TElemTo>, 
             TPredicate> 
        where(const TPredicate &predicate)
    {
        return filter<TElemTo, 
                        TElemTo,
                        const_iterator, 
                        pass_thru<TElemTo>, 
                        TPredicate>
                    (begin(),
                     end(),
                     pass_thru<TElemTo>(), 
                     predicate);
    }
};

All the real work is done by the nested const_iterator class, which performs skipping using the predicate in the ++ operator and performs transformation using the 'selector' in the * operator.

It's quite an unwieldy class to construct, what with all those type parameters and actual parameters, but we can make it much easier by providing a free function called from:

template <class TCollFrom>
filter<typename TCollFrom::value_type, 
         typename TCollFrom::value_type,
         typename TCollFrom::const_iterator, 
         pass_thru<typename TCollFrom::value_type>,
         always_true<typename TCollFrom::value_type> >
    from(const TCollFrom &from)
{
    return filter<typename TCollFrom::value_type, 
                    typename TCollFrom::value_type, 
                    typename TCollFrom::const_iterator, 
                    pass_thru<typename TCollFrom::value_type>, 
                    always_true<typename TCollFrom::value_type> >
                (from.begin(), 
                 from.end(), 
                 pass_thru<typename TCollFrom::value_type>(), 
                 always_true<typename TCollFrom::value_type>());
}

This does nothing much apart from wrapping a real container inside an instance of filter, and switching off all filtering or transformation, so we can then call the where or select members. As those members also return instances of filter, this gives us a convenient "fluent interface". Those concerned about performance should be reassured that the compiler ought to be able to inline away all of this syntactical plumbing when it sees the trivial definitions of pass_thru and always_true.

For example, filter a list of integers and turn them into quoted strings:

std::vector<int> vecInts;
vecInts.push_back(5);
vecInts.push_back(2);
vecInts.push_back(9);

auto filtered = from(vecInts)
    .where([] (int n) { return n > 3; })
    .select<std::string>([] (int n)
        { return "\"" + 
                 boost::lexical_cast<std::string>(n) + 
                 "\""; });

for (auto i = filtered.begin(); i != filtered.end(); ++i)
    std::cout << *i << std::endl;

And that prints:

"5"
"9"

How is this select function different to std::transform? Because it is evaluated lazily. None of the work is done until we are in the final for loop, and I could break out of that early if I wanted to.

The one irritation is the fact that I have to tell select what the output value type will be, even though the compiler can lambda deduce it from the lambda in this case. Why can't the compiler join up the dots for us? In fact, in a full implementation of C++0x, it could, but I don't yet have access to such a compiler. Here's how I believe it would work.

First, we need the decltype keyword, which yields the compile-time type of any expression. Suppose we have something function-like of type TSelector, and we want to know what it would return when called. We also happen to know that it takes one parameter of type TElemTo (because we're taking the output of the previous filter).

So we need an instance of TSelector:

TSelector()

And then on that, we need to call it, passing it an instance of TElemTo:

TSelector()(TElemTo())

And then we want the type of that expression:

decltype(TSelector()(TElemTo()))

Hey presto, we might think: this can replace the TElemTo2 type parameter, so callers would no longer need to write select<std::string>.

But I suspect this won't work, because it's very likely that TSelector will not be default-constructible (if it is a lambda that captures by reference, for example). The trick in such situations is a make_ptr function:

template <class T>
T *make_ptr() { return (T *)0; }

It actually returns a NULL pointer of the specified type. We can then define a make_ref that turns that into a reference, and our expression becomes:

decltype(make_ref<TSelector>()(make_ref<TElemTo>()))

Of course, if that particular operation was ever executed, it would result in major crash-ola. But it never will be executed; decltype doesn't execute the expression, it just figures out the resulting type.

Then we can get rid of TElemTo2, and our example call looks like this:

auto filtered = from(vecInts)
    .where([] (int n) { return n > 3; })
    .select([] (int n) { return "\"" + 
                         boost::lexical_cast<std::string>(n) + 
                         "\""; });

I hope decltype makes it into MSVC++ version 16.

Wednesday, 10 December 2008

Optimizing Aggregate for String Concatenation

Linq lets you think in a very generally applicable way and solve a very wide variety of problems with a few key concepts. That’s a great thing. But it’s irritating when the elegant solution doesn’t perform as well as an ugly special case.

Using a combination of well-known Linq features I’m going to demonstrate that we already have the power to get the best of both worlds: speed and elegance.

One example that has always irked me (and which is simple enough to demonstrate the idea with) is this:

Enumerable.Range(0, size) 
          .Select(n => n.ToString())
          .Aggregate((a, b) => a + ", " + b);

It’s got all the attributes of a beautiful Linq-style solution – a single expression that produces the thing we want, using very general operations that are parameterized by self-contained functions.

But if size gets large, it’s dreadfully slow. The reason is that Aggregate takes the first two items, uses the function to combine them, then you can kind of imagine it putting the result back on the start of the list to replace the original two items. So each time it does that, the list shrinks, until eventually there’s only one item left, which it returns. All very logical and beautiful – the items on the list are from a set and we have defined a closed binary operation on them, so I guess it’s a magma.

But that first item is an ever-growing string, and each time around it has to be copied into a new string. This is a recipe for disastrous performance. To get faster performance, we need to use a different function, which I’ll call Oggregate:

public static string Oggregate(this IEnumerable<string> source, string delimiter)
{
    StringBuilder builder = new StringBuilder();
 
    builder.Append(source.First());
    foreach (string s in source.Skip(1))
    {
        builder.Append(delimiter);
        builder.Append(s);
    }
 
    return builder.ToString();
}

But this is irksome, because you have to know when to use this optimized version, and then you have to know how to modify your original code. You can’t just flick the “go faster” switch.

A good programming language defines general concepts that compose (go together) well. A good compiler then takes programs written in that language and does terrifying things to them, without telling you, so that they still do what you asked, but they do it fast. The compiler does this by spotting patterns and saying “Ah, I see what you’re trying to do. I know a faster way to do that.” You don’t have to explicitly tell it to do it the fast way. It just notices the pattern and makes the smart decision. Such capabilities are called compiler optimizations. They’re “turnkey” solutions, in the sense that all you have to do is turn the key and they start up. You don’t typically have to think too hard about it. Somebody already did that for you.

So my ideal solution for the above problem would be for the compiler (or a library) to notice the pattern I’m using and use the StringBuilder approach instead. If I’m not using that pattern, it should fall back to doing what it usually does.

I can’t change the compiler, so can I write a library? The problems facing us are three fold:

  • We want to replace the standard library’s version of an algorithm that can operate on any sequence.
  • We only want to do that for sequences of strings.
  • We only want to do it if the function parameter has a very narrowly-defined shape.

Skipping the first one for now, the solution to the second problem is to write a version of Aggregate for the special case of string sequences. The solution to the third is clearly going to involve Linq expressions, as they give us a way to examine the structure of simple expression-like functions, and also to apply such a function to some parameters if necessary:

public static string Aggregate(this IEnumerable<string> source, 
                 Expression<Func<string, string, string>> func)
{
    ... look at the func to decide what to do

Having defined such a function in some namespace, what happens if we add a using directive at the top of the source file where we want to use it? That’s no good, because the compiler has two choices for which function to use. In C++, the thing we’ve written is a kind of “template specialization”, and the rules for template resolution in C++ usually mean that the most specialized choice is the one that the compiler picks. But this isn’t the case in C#. The compiler just gives up and says that we’re being ambiguous.

But if we put our using directive inside a namespace block, then the C# compiler is happy to assume that it should select our version of Aggregate:

using System;
using System.Linq;
using System.Diagnostics;
 
namespace ConsoleApplication5
{
    using Optimizations.AggregateStringBuilder;
 
    class Program
    {
        static void Main(string[] args)
        {

The location of the using directive affects the overload resolution priority assigned to the functions in that namespace. So we can switch on our optimisation at the level of a namespace block. I’m satisfied with that – it constitutes an on/off switch, for my purposes.

Here’s what the Aggregate function looks like:

public static string Aggregate(this IEnumerable<string> source, 
                        Expression<Func<string, string, string>> func)
{
    BinaryExpression root = func.Body as BinaryExpression;
    if (root != null)
    {
        if (root.NodeType == ExpressionType.Add)
        {
            BinaryExpression left = root.Left as BinaryExpression;
            if (left != null)
            {
                if (left.NodeType == ExpressionType.Add)
                {
                    ParameterExpression leftLeft = 
                        left.Left as ParameterExpression;
 
                    if (leftLeft != null)
                    {
                        ConstantExpression leftRight = 
                            left.Right as ConstantExpression;
 
                        if (leftRight != null)
                        {
                            ParameterExpression right = 
                                root.Right as ParameterExpression;
 
                            if (right != null)
                            {
                                if ((leftLeft.Name == func.Parameters[0].Name) 
                                  && (right.Name == func.Parameters[1].Name))
                                    return source.Oggregate(
                                        (string)leftRight.Value);
                            }
                        }
                    }
                }
            }
        }
    }
 
    return source.Aggregate(func.Compile());
}

In other words, it looks pretty ugly. But that’s optimizations for you. It really just looks at the lambda to see if it fits a very rigid pattern: (a + c) + b, where a and b are the parameters to the lambda and c is a constant. If so, it calls Oggregate. Otherwise, it falls back to letting the compiler run the lambda as it usually would. A compiled delegate doesn’t match our Expression<T> argument, so the normal version of Aggregate is called.

This means that, where it’s an appropriate optimization, all it does is examine a few enum properties, perform a few casts, compare a couple of strings and then call Oggregate. So all the extra work (which is very minor) happens outside the loop.

The remaining question is, how badly does it hurt performance when it isn’t an appropriate optimization? As usual, it depends greatly on how you use it. If you’re using Aggregate to concatenate a small number of strings, the compilation step is wasteful to be sure. But again, it happens outside the loop. And in any case, if you find that your program runs slower, it’s just as easy to switch off the optimization as it is to switch it on.

So in conclusion, although this example is pretty simple and so not exactly earth-shattering in itself, it serves to demonstrate how C# gives us the tools to introduce our own turnkey optimizations for special cases of the very general algorithms available in Linq, which was a pleasant surprise for me.

I posted this as a quiz question on Stack Overflow. The reaction to the idea of someone posting a question as a quiz was quite mixed – the votes for the question went negative a few times before averaging out at zero. I think this is a good use of the site, because the end result is a question with an answer and some associated discussion to give more detailed background, alternative approaches, etc. I think it annoyed people who didn’t know the answer, because (as I would freely admit) part of the reward of using Stack Overflow is the ego-boost of handing out knowledge to those in need. If you meet someone who already knows the answer to their question, and then – even worse – you don’t know the answer, then it kind of spoils the fun for you (one guy in particular seemed quite upset). But the fact remains that such an exercise produces the same kind of valuable addition to the site.

Thursday, 13 November 2008

Chain – a LINQ operator for dealing with Linked Lists

I don’t think there’s anything in LINQ that will do this, though I expect I’m wrong - I have a tendency to write my own extension method to do something and then discover that LINQ already provides a general version of it. But in the mean time, here’s my Chain method:

public static IEnumerable<T> Chain<T>(this T first, Func<T, T> follow) where T : class
{
    for (T item = first; item != null; item = follow(item))
        yield return item;
}

It’s designed to be used in any situation where a traditional linked list exists. I used it in my AutoDisposal library to get a list of all the types inherited by a given type. It chains a bunch of objects together into an enumerable list by following links between them.

The irritation that provoked this minor burst of creativity is that if you use the GetFields method of Type, there doesn’t seem to be a simple way to get all the instance fields in that type, including inherited ones. By default, GetFields does include inherited fields, but only public ones. To get all public and non-public instance fields, including all inherited ones, you have to walk the chain of base types and get the fields declared in each type. So you’d better use BindingFlags.DeclaredOnly, or you’ll end up with duplicates of the public fields.

I wanted to write a LINQ expression that would get me a single flat list of all the fields in a type, so this is how I used Chain as part of it:

instance.GetType()
    .Chain(type => type.BaseType)
    .SelectMany(type => type.GetFields(BindingFlags.Instance | 
                                       BindingFlags.Public | 
                                       BindingFlags.NonPublic | 
                                       BindingFlags.DeclaredOnly))
    

In this case, the BaseType property of Type is the “next item” pointer in the linked list I’m interested in, but to use LINQ effectively we need it in the form of an IEnumerable<Type>, and so Chain provides a nifty way to do that.

Shouldn’t something like Chain be in the BCL (if it isn’t already?)

Wednesday, 12 November 2008

AutoDisposal using PostSharp

I complain to anyone who will listen about the poor language support in C# for the IDisposable interface. Yeah, we’ve got the using statement, and that’s fine as far as it goes.

But compare that to what C++/CLI has: the most complete support of any .NET language. Not just the equivalent of the using statement, but also automatic implementation of IDisposable that takes care of disposing of nested owned objects, including inherited ones, like magic (relatively speaking, unless you’re a C++ programmer in which case you’ve taken it for granted for a decade or two).

The relationship between deterministic clean-up (i.e. destructors) and garbage collection (i.e. finalizers) was quite vaguely understood until Herb Sutter clarified as part of his work on C++/CLI. But now it’s all very clear how it should work – the only problem is, there doesn’t seem to be any movement towards fixing it in any future version of C#.

Anyway, by now you’re probably bored of the ranting and wondering where the code snippets are. So here’s one:

class FunkyResource : IDisposable
{
    public string Label { get; set; }
 
    public void Dispose()
    {
        Console.WriteLine("Disposing " + Label);
    }
}

Not particularly impressive, I grant you, but it serves as a dummy example of a class that represents some resource that needs to be cleaned up. Here we just log the fact that a given instance is being cleaned up, identifying it with a label string.

Here’s where it gets interesting:

[AutoDisposable]
class FunkyOwner
{
    [AutoDispose] 
    private FunkyResource _resource1 = new FunkyResource { Label = "resource1" };
 
    [AutoDispose] 
    private FunkyResource _resource2 = new FunkyResource { Label = "resource2" };
}

This class owns a couple of FunkyResource instances. By “own” I simply mean that when an instance of this class is disposed of, those two resource instances must also be disposed of.

But wait a second – how does FunkyOwner implement IDisposable? The answer is that it automatically does so, because of that [AutoDisposable] attribute.

This is all thanks to the wonderfully powerful PostSharp, which effectively allows you to extend any CLR-based language through custom attributes. And because PostSharp builds on the CLR in a language-independent way, this means that the extensions you create should work in any CLR-based language that supports attributes.

Very briefly, PostSharp registers an extra step in the compilation process of Visual Studio: after your output assembly is built, a program called PostSharp.exe takes a look at it, and performs additional processing on the raw IL in the assembly. And hey presto, extra features make their way into your assembly.

Before we see how this example works, what about inheritance?

class DerivedOwner : FunkyOwner
{
    [AutoDispose] 
    private FunkyResource _resource3 = new FunkyResource { Label = "resource3" };
}

Note that because we’re deriving from a class that has the [AutoDisposable] attribute, we don’t need to specify it again (it will be ignored if we do). If we call Dispose on an instance of DerivedOwner, we get this output:

Disposing resource3
Disposing resource1
Disposing resource2

That is, the resources owned by DerivedOwner are disposed of first, then the base class’s resources are also disposed of. So inheritance works fine.

And what about a mixed scenario, where I want automatic clean-up of owned resources but I also want to run some custom code of my own during disposal?

class MixedOwner : IDisposable
{
    [AutoDispose]
    private DerivedOwner _owner2 = new DerivedOwner();
 
    public void Dispose()
    {
        Console.WriteLine("Disposing MixedOwner");
 
        this.TryDisposeFields();
    }
}

Note the call to TryDisposeFields(), an extension method I cooked up (see below). The reason for the prefix ‘Try’ is that you can call it on anything and it will look for fields marked with the [AutoDispose] attribute. If it finds any, it will dispose of them. If it doesn’t find any, that’s okay – nothing happens.

When manually implementing IDisposable like this, consider making it virtual, so that derived classes can override it, although they must of course call the base class’s version after performing their custom cleanup. It might be good practice in some circumstances to follow the pattern where you have a separate virtual method Dispose(bool) instead. However, that is really intended to allow you to implement a finalizer and a Dispose method together, and these days there are almost no circumstances in which it is recommended that you write a finalizer (unfortunately a lot of old books give out-of-date advice here).

Also note that we don’t need the [AutoDisposable] attribute on the class, as we already implement IDisposable (again, it would have been harmless to add it).

Unsurprisingly, the output of disposing an instance of MixedOwner is:

Disposing MixedOwner
Disposing resource3
Disposing resource1
Disposing resource2

All very nice. And extremely easy to implement, using the “easy” mode of PostSharp which is known as Laos. No need to directly manipulate IL, just write classes to represent your attributes, deriving from base classes that take care of the messy details.

My [AutoDispose] attribute is actually completely trivial because it’s just a simple marker on fields that I look for using reflection. So this isn’t inherently anything to do with PostSharp:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class AutoDisposeAttribute : Attribute { }

Where PostSharp makes an appearance is in the [AutoDisposable] attribute:

[Serializable]
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class AutoDisposableAttribute : CompositionAspect
{
    public override object CreateImplementationObject(InstanceBoundLaosEventArgs eventArgs)
    {
        return new AutoDisposableImpl(eventArgs.Instance);
    }
 
    public override Type GetPublicInterface(Type containerType)
    {
        return typeof(IDisposable);
    }
 
    public override CompositionAspectOptions GetOptions()
    {
        return CompositionAspectOptions.IgnoreIfAlreadyImplemented;
    }
}

By inheriting the attribute from PostSharp.Laos.CompositionAspect, I’m saying that I want to add an extra interface to any class marked with my attribute. The implementation is created and returned from the CreateImplementationObject method. The other overrides are pretty self-explanatory.

Here’s what my AutoDisposableImpl class looks like:

public sealed class AutoDisposableImpl : IDisposable
{
    private readonly object _instance;
 
    public AutoDisposableImpl(object instance)
    {
        _instance = instance;
    }
 
    public void Dispose()
    {
        _instance.TryDisposeFields();
    }
}

Pretty simple, eh? It just stores a “back pointer” to the object we are extending, so it can call the TryDisposeFields extension method on whatever that object happens to be. In a way, it’s just like MixedOwner except it doesn’t do anything extra.

Actually most of the complicated mess is hidden in that extension method. So here’s the gory detail:

public static void TryDisposeFields(this object instance)
{
    instance.GetType()
        .Chain(type => type.BaseType)
        .SelectMany(type => type.GetFields(BindingFlags.Instance | 
                                           BindingFlags.Public | 
                                           BindingFlags.NonPublic | 
                                           BindingFlags.DeclaredOnly))
        .Where(fieldInfo => fieldInfo.GetCustomAttributes(typeof(AutoDisposeAttribute), false)
                                     .OfType<AutoDisposeAttribute>().Any())
        .Select(fieldInfo => fieldInfo.GetValue(instance))
        .OfType<IDisposable>()
        .ForEach(field => field.Dispose());
}

As you can see, I enjoy chaining a lot of LINQ operators together. The first one, Chain, is a little custom gadget of mine that turns any linked list of T into an IEnumerable<T>. I’ll describe it in a separate post.

After that, I get all the fields of all the types in the inheritance chain into a flat list, using the marvelous SelectMany method. Then I filter them according to whether they have the [AutoDispose] attribute, and select the values of the remaining fields, then filter again based on whether they support IDisposable, and finally I dispose of each one. (That last ForEach method is another one of mine, and I’ve seen a lot of people suggesting the same thing).

So what are the drawbacks of this marvelous scheme? The one major issue with the PostSharp approach is that the Visual Studio IDE does its own compilation of your source to provide auto-completion and other kinds of “intellisense”. It doesn’t look at the assembly on disk, because there might not be one (e.g. if the code doesn’t completely compile without errors yet, as is often the case when you are adding new code, which is precisely the time when you require intellisense features).

This means that the IDE doesn’t know that [AutoDisposable] classes support IDisposable. Nor does the real compilation stage that happens during the build. PostSharp doesn’t kick in until after the compilation has completed. The upshot is that we cannot do this:

using (new FunkyOwner())
{
    Console.WriteLine("Using FunkyOwner...");
}

The using statement needs to statically verify that the object supports IDisposable. It won’t try to resolve this at runtime.

This would seem to be not so much a drawback, more a total friggin’ disaster. However, there is a solution, in the form of another generally applicable extension method:

public static void TryUsing<T>(this T instance, Action<T> action)
{
    try
    {
        action(instance);
    }
    finally
    {
        IDisposable disp = instance as IDisposable;
        if (disp != null)
            disp.Dispose();
    }
}

Now we can write:

new FunkyOwner().TryUsing(funkyOwner =>
{
    Console.WriteLine("Using FunkyOwner...");
});

I arranged the interface of the TryUsing method carefully in order to mimic the characteristic of the using statement. In particular, the object to be disposed of is only given a name by the lambda parameter. This means that it cannot be accidentally used outside of the block where it is “in scope” (i.e. still not yet disposed), unless the programmer makes a special effort to circumvent this protection by storing a reference to the object in a variable declared outside the lambda.

And with that, I have now discussed every single part of the AutoDisposal library. You can download the complete source along with a demonstration program here:

http://www.earwicker.com/AutoDisposalSource.zip

You will of course also need the PostSharp system, which you can get here:

http://www.postsharp.org/download/