Monday, August 28, 2006

Specfiying Ownership

Raymond Chen's post today, railing against boolean parameters, reminds me of a small detail that made one of my APIs easier to use.

The reason boolean parameters are bad is that it's often hard to figure out, from reading the code, what 'true' and 'false' refers to. Raymond points to StreamReader's constructor overload, StreamReader(Stream, bool). In this case, the boolean argument applies to the ownership of the stream - that is, will the StreamReader dispose of the Stream when it itself is disposed? Update:No it doesn't - a salutary reminder of the problem with boolean arguments! It indicates whether or not the StreamReader pays attention to byte order marks. In any case, my comment below refers to resource ownership.

For this situation in my own APIs, where transferral of ownership needs to be flexible, I use a little enum:

/// <summary>
/// Describes who controls a resource that is transferred between objects.
/// Useful for negotiating who should call IDisposable.Dispose when done.
/// </summary>
public enum ResourceOwnership
{
    /// <summary>
    /// Don't change the status quo regarding ownership of any resources.
    /// </summary>
    Preserve,
    
    /// <summary>
    /// The ownership is transferred to the callee in the case of a resource setter, 
    /// or transferred to the caller in the case of a resource getter.
    /// </summary>
    Transfer
}
I'm not 100% happy with the name of the first option, Preserve, but I can't think of a better one. Anyway, the little insight behind the enum is that rather than thinking about source and destination ownership as you interact with a class and hand it a resource, you think about how you're changing the existing ownership (i.e. transfer) or preserving the status quo. From a calculus perspective, the enum describes the derivative of the ownership, rather than the ownership itself. I find this works better than a boolean, which tries to describe the ownership directly, and also better than a special-purpose enum which contextualizes the ownership.

No comments: