Language Envy - episode 0
Although C# is the language that I can call myself proficient enough to make a living these days, there are other languages that I have to use for specific tasks (like JavaScript, SQL, XSLT.) I also like using other general purpose languages for pure exploration or pet projects. I'd include Ruby, ObjectiveC and PHP in this group.
When using other languages it often happens that I encounter features that I wish C# had or that the C#-equivalent was as easy (it works both ways — I miss some C# feature on the other side as well.)
In this series of undetermined length I will be posting some of the items from my wish list as I remember them.
The case
statement
To start things off, let's check out C#'s case statement, straight from the language specification.
switch-statement: switch ( expression ) switch-block switch-block: { switch-sectionsopt } switch-sections: switch-section switch-sections switch-section switch-section: switch-labels statement-list switch-labels: switch-label switch-labels switch-label switch-label: case constant-expression : // <-- line 14 default :
I know that doesn't look like C# code. What I'd like to point is in line 14. The
expression in each case
label has to be a constant. I'm sure that helps
making the switch
statement compile to a very efficient MSIL code, but
let's consider what we are missing because of that.
Here's a sample of what you can do in a Ruby case
expression.
Months = %w(JAN FEB MAR APR MAY\ JUN JUL AGO SEP OCT NOV DEC) def get_month(value) case value when Date # class name (instance of?) return Months[value.month - 1] when /\d{4}-(\d{2})-\d{2}/ # Regular expression (matches ?) return Months[$1.to_i - 1] when 1..12 # Range of values (contained ?) return Months[value - 1] end end puts get_month(Date.today) puts get_month("2008-10-20") puts get_month(8)
As you can hopefully see in the above example, the expressions in
each when
statement do not need to be constants
(class names like Date
are constants, by the way)
Ruby defines the ===
(triple equal) comparison operator
that can be overriden in each class and is used in the case
expression to test each when
condition. This is usually read
as "when value matches with this expression here...".
Not surprisingly, the built-in classes in Ruby do override the triple
equal operator to add a more meaningful implementation for it.
Range
matches the values that are within the range. RegExp
matches
values that agree with the regular expression, Class
objects
match values that are instances of that class, etc.
I use this feature all the time and it's so convenient that I'd be thrilled to see it in C# one day.
So, what is my suggestion?
I wouldn't be a real programmer if I didn't try to sell my own suggestion, would I? Since
IComparable
is taken and means something different, I was thinking of maybe
something like this.
public interface ICanMatch