Another interesting Ruby feature should eventually become available in C# and VB.NET. Consider the following Ruby code (from the book Programming Ruby):

module Summable
  def sum
    inject {|v,n| v+n }
  end
end
class Array
  include Summable
end
[ 1, 2, 3, 4, 5 ].sum -> 15

The idea is that in order to overcome Ruby's single inheritance you can group code in modules and just include it in your classes - the methods automatically become member methods of the instances of your class (the situation is actually a bit more complicated and detailed discussion is out of scope of this blog post).

In order to achieve this in C# we'd have to use LINQ preview (therefore this functionality is not going to be available for quite some time) and write something like this:

static class Summable
{
  public static int Sum(this IEnumerable<int> arg)
  {
    int s = 0;
    foreach(int i in arg)
      s += i;
    return s;
  }
}
// new int[] { 1, 2, 3, 4, 5 }.Sum() -> 15

Several things are important to note here. First, we have to struggle with generics in order to generalize a bit the extension method(s). Second, due to the relatively narrow choice of generic type(s), I couldn't have written

T Sum<T>(this IEnumerable<T> arg) where T:??

because you can't assign 0 (zero) to any T and you can't use += operator on any T. At the same time, you can't find suitable type to replace question marks as well, so we are stuck with "hard-coded" ints. Ruby allows for any type that supports + operator.

I can only guess that a VB.NET version could actually be pretty close to Ruby and allow for more flexibility at the cost of runtime evaluation (and possibly error whereas with C# you are guaranteed a compile time error if there is any).

Either way, using early or late bound style, this is cool as it allows yet another simple but powerful way to extend functionality of your classes without inheritance. In fact (I just tried) it allows you to extend sealed classes with new methods!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
0 Comments