In the limited amount of time that I have played around with Ruby, I have been impressed with how easy it makes a lot of things. Utilizing the power of blocks, it is this simple to print out the contents of an array.
list.each {|item| puts item}
C# 2.0 gives you something similar to blocks with the new anonymous methods. Say you want to show a message when a button is clicked. Before 2.0 you had to do quite a bit of coding to implement the feature.
First, you have to implement your method.
private void button1_click(object sender, EventArgs e)
{
MessageBox.ShowMessage("Hello, World!");
}
Then you have to assign the method to the click event.
button1.Click += new System.EventHandler(button1_click);
With anonymous methods, this task becomes much simpler.
button1.Click += delegate { MessageBox.Show("Hello, World!"); };
Granted, if you had a decent designer, most of this would be done automatically, but you can still see how much easier stuff like this is in C# 2.0.
After looking at the examples for anonymous methods, it got me thinking about whether you could implement methods on a list class similar to the way Ruby does. So I started by making a delegate method, and a descendent of ArrayList.
delegate void EachDelegate(Object item);
class MyCoolList: ArrayList
{
public void Each(EachDelegate delegateMethod)
{
foreach (object obj in this)
delegateMethod(obj);
}
}
Now, to print out the contents to the command line.
MyCoolList list = new MyCoolList();
list.Add("foo");
list.Add("bar");
list.Add("baz");
list.Each((EachDelegate)delegate(object obj) { Console.WriteLine(obj.ToString()); });
The syntax is a little ugly, but at least all of the code is there in the same method. Now that I have a class that implements each, lets look at leveraging generics to make the class, well more generic.
First we need to make our delegate generic.
public delegate void EachDelegate<ReallyCoolListElement>(ReallyCoolListElement element);
Then we make our list class descend from List<T> and use the new generic delegate in our Each method.
class MyReallyCoolList<ReallyCoolListElement> : List<ReallyCoolListElement>
{
public void Each(EachDelegate<ReallyCoolListElement> delegateMethod)
{
foreach (ReallyCoolListElement obj in this)
delegateMethod(obj);
}
}
To use this new class we can modify the original code to look like this.
MyRealyCoolList<string> list = new MyReallyCoolList<string>();
list.Add("foo");
list.Add("bar");
list.Add("baz");
list.Each((EachDelegate<string>)delegate(string element) { Console.WriteLine(element); });
Or if you wanted to use it to sum up a list of ints.
int sum = 0;
MyRealyCoolList<int> list = new MyReallyCoolList<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Each((EachDelegate<int>)delegate(int element) { sum += element; });
The syntax in C# is not nearly as nice and sugary as Ruby, but this does demonstrate some of the cool new features that are being added to C# 2.0.