Thursday, April 9, 2015

Adding Action to your .Add

I've learned not to be intimidated by C#'s rich library for delegate and lambda operations.  In fact, I've come to embrace Func and Action as tools to simplify APIs and keep my code clean.  One pattern I really liked when I first saw it, and try to encourage its use, is offering an override along the lines of .Add<T>(Action<T> aNewT) any time an API exposes the ability to add something to a collection.

The vendors of server-side web controls all use this pattern for adding columns to a grid control. First consider the delegate-less approach:

GridColumn myColumn = new GridColumn();
myColumn.Title = "Name";
myColumn.Sortable = true;
myColumn.Filterable = true;


Maybe we can clean things up a little by declaring the new anonymous object within .Add method call:

mySuperGrid.Columns.Add(new GridColumn() 
      Title = "Name";
But most of the time, won't I always want to add a new object?  So why make me bother to type "new"?  And if I can only add GridColumn types, why make me type that too?  So consider the following override for the .Add method:

public void Add(Action<GridColumn> initializerDelegate)
       GridColumn newColumn = new GridColumn();
       //We could even do some default intialization if it wasn't already done in GridColumn's 


Now look what a consumer of the API can do:


In my opinion, this is much cleaner and simpler for consumers of the .Add method.  Note the consumer doesn't have to know the name of the type used to represent a new column, nor worry about correctly instantiating a new instance of one. Compile-time binding and Intellisense still apply!

So don't fear "=>", it really is your friend!

No comments:

Post a Comment