Better C# - Anonymous Delegates
C# has been kind of in and out of my life since its inception way back when. At one point I really liked it, then I started to despise it because of how garbage collection works and how easy it is to leak resources when you aren't proactively destroying object instances.
Luckily the IDispose interface is available to take care of such things, and you can often achieve the same effect through use of a try/catch/finally clause, ensuring resources are released during a visit to the finally block.
I generally use the try/catch/finally approach because I find it more obvious and I don't have to wrap up existing classes with an IDispose implementation.
Another one of my frequent gripes about C# is how verbose it is. The latest generation of C# will introduce a form a type inference that will improve on this in a big way. For now there are still some things we can do to make our active code smaller and more manageable.
Today I used anonymous delegates to clean up some code and remove a lot of repeated junk.
The pattern I had went something like this:
public static string create(string name) { IDbConnection db = new System.Data.SqlClient.SqlConnection(); try { db.ConnectionString = connect_string_for(null); db.Open(); IDbCommand command = db.CreateCommand(); command.CommandText = string.Format("CREATE DATABASE {0}", name); command.ExecuteNonQuery(); } catch (System.Exception x) { return x.Message; } finally { if (db != null && Tools.included_in<ConnectionState>(db.State, Tools.db_open_states)) { db.Close(); } } }
Using anonymous delegates (also known as anonymous methods) I was able to extract the repetitive junk, namely the try, catch, and finally stuff plus the db connection piece into a reusable method that named with_db_for that took the name of the database and the delegate for using the database. Now that code looks like this:
public string create() { string result = Tools.with_db_for(null, delegate(IDbConnection db) { IDbCommand cmd = db.CreateCommand(); cmd.CommandText = string.Format("CREATE DATABASE {0}", dbname); cmd.ExecuteNonQuery(); return "yes"; }); dropped = result == "yes"; return result; }
Ahhh, much better.
I'm going to have to keep exploring this. Anonymous delegates are lexical closures which is very satisfying, but they are also strongly typed which is weird for such constructs. I am very pleased with this.
The future looks even better. I am really interested in type inference and many of the other benefits of the next generation of C#, and perhaps my mind will change a little and I'll actually start enjoying it once more.
But never as much as I enjoy Ruby.