Sunday, May 1, 2011

(cautiously) Using extension methods to make (cleaner?) code.

I’ve read allot of warning as I learned about extension methods.  To me they have a similar “feel” to them as macros did in C/C++.  The trap that exists is the ability to make a complicated contraptions that seem really slick when coding but aren’t actually a good thing in the long run – i.e. down the road either you or someone like you will spend more time figuring out what is going on than it’s worth.

Still, I’m using them here and there.  I tell myself I’ve gone down the bad road of complexity in my past experience enough to keep it under control.

But the feeling in the back of my mind is that I’m playing with fire.

Time will tell.

Maybe I’ll come back to this in a half a year and note if I was right to be cautious.

Example Scenario: You are using a BindingSource with a DataSet and a DataGridView.  You want to access the row but it’s a pain to cast twice.

(DataSet1.MyDataRowType)(((DataRowView)(bindingSource[rowIndex])).Row)

I could write a private member function but it would be a one off.   I could write a public static helper member function, but I’d end up with a different style of code:

MyUtility.GetRowAt<DataSet1>.MyDataRowType>(bindingSource, rowIndex)

That’s not really bad.

And the extension method version isn’t much different.

static class MyExt
{        
internal static T
DataRowAtX<T>(
this BindingSource bs, int i)
where T : class
{
return ((DataRowView)bs[i]).Row as T;
}
}

However, with the extension method, my code doesn’t switch over to the “utility call” style, which to me, brings the level of indirection, and the associated complexity more the fray than:

bindingSource.DataRowAtX<DataSet1.MyDataRowType>(e.RowIndex);
Just like macros, my code is what I want it to be right now, and I got around a limitation by leveraging a language feature providing generic extensibility.
So the question is: will I regret this?