More on "bools, structs or enums"
There were some points about my previous post that I thought it might be worth bringing up in a new entry. It seems that in general, most people agree that the set of bool parameters are a bad idea. I found this a little surprising, given how often I've seen it. Maybe it's just the code-bases I've inherited :)
Fluent Interfaces
Someone pointed out that an alternative to using object initializers from C# 3.0 is to use Fluent Interfaces. Indeed, this is exactly what I would have done before object initializers were around. Jay and I have been talking about the idea of Fluent Interfaces and how they relate to "builder" classes for data classes for more than a year now.
Here's an example of how a Fluent Interface might be used instead of a collection initializer in the previous blog entry's context
struct DisplayUserOptions{ bool email; bool phoneNumber; public DisplayUserOptions SetEmail(bool yes) { email = yes; return this; } public DisplayUserOptions SetPhoneNumber(bool yes) { phoneNumber = yes; return this; }}
And it can be called inline in a way similar to the object initializer syntax:
DisplayUser(user, Console.Out, new DisplayUserOptions().SetEmail(true).SetPhoneNumber(false));
Extensibility
Numerous people pointed that both the enum and the struct option produce more extensible API's than passing bools. In general I consider myself more of an application writer than a library writer, and so I tend not to worry as much about extensibility. This doesn't mean that I feel like I don't need to think about whether an API is usable or not, but rather that I don't tend to worry about changes that require me to recompile dependent assemblies. However, this does bring up a separate point. When I do code reviews I like them to contain meaningful changes, and so it's nice that with either the the enum or struct option the only places that change are the options type itself, and the callers who care about the new option. Conversely, with the bool option, all callers need to be updated.
Extension methods for enums
I said in my previous post that one of the advantages of using structs is that it gives you a place to group behavior that belongs with the options. Someone pointed out to me that with C# 3.0, you can use extension methods to add functionality to your enums. This is a good point. I'll have to think more in the future about whether I feel comfortable using an enum together with some extension methods, as opposed to a struct or class.
Thanks for the great feedback! Keep it coming.
EDIT: Added an example of a Fluent Interface for this scenario.
EDIT 2: Fix the implementation of the Set methods in the example. Thanks Jay!
EDIT 3: Change section header to be "extension methods for enums", instead of "Extension methods for interfaces". Oops
Comments
Anonymous
December 10, 2007
I think you missed a 'return this;' in your fluent interface example.Anonymous
January 02, 2008
Welcome to the thirty-eighth Community Convergence. These posts are designed to keep you in touch with