To make good on my
threat
, here are a few thoughts on the
C# 3.0 features that I
find interesting, along with a grade and a few thoughts:

Implicitly typed local variables:    A

I have been asking for this feature in Java for years.

Why do I need to
write:

Account a = new Account();
Employee e = (Employee) employees.get("John")

Instead of

a = new Account();
Employee e = employees.get("John")

Can’t the compiler figure this out for me?  Of course, it can.

Generics solve the second case, but they add more type inference envy than
ever:

List<Map<String, Name> employess = new ArrayList<Map<String, Name>>();

Surely we can do a bit better than that, right?

Well, that’s exactly what type inference will bring you.  Combine strong
typing with a strict application of the DRY principle and you get the best of
both worlds.

Extension methods:    C

This feature lets you add methods to a class outside the definition of that
class.  The syntax is a bit peculiar:  you add this to the first
parameter of your method:

public static int ToInt32(this string s) {
  return Int32.Parse(s);
}

I prefer Ruby’s syntax for this:

def string.toInt32()
  …
end

Note that this feature doesn’t break encapsulation:  extension methods
don’t have access to private fields or methods of the class they extend. 

As for the feature itself, I have to admit it frightens me somewhat (both in
Ruby and C# 3.0) because it becomes really hard to know exactly the
contract that classes abide by, and also where the extra definitions are coming
from.  I have to admit that over the years, I have grown quite fond of
Java’s rigid "one public class per file" rule and I’m afraid that extension
methods might resurrect the C++ header nightmares that haunted C++ programmers
for decades. 

On the other hand, this kind of
extensibility opens the door for some very interesting tricks, such as the ones
used by Ruby on Rails to exercise its magic (more on that in another post).

Time will tell.

Lambda Expressions:    B+

I have no doubt that functional programmers are screaming in frustration to
hear the term "lambda expression" hijacked to mean "closure".  Let’s put
the intellectual debate aside and observe that closures are extremely useful. 
C# already had a head start over Java with delegates and is now pulling further
ahead with closures.  Let’s hope Java will follow suit.  The C# syntax
is fairly straightforward:

(int x) => x +
1

defines a lambda
expression that accepts an integer parameter and returns that parameter
incremented by one.  You can then pass this lambda expression around as
real object.  I am quite looking forward to using this feature more.

Query
Expressions:    C-

This feature is
also referred to as LINQ for "Language Integrated Query".  The idea is to
allow a certain subset of relational language inside C#:

customers.
 
Where(c => c.City == "London").
 
SelectMany(c =>
      c.Orders.
      Where(o => o.OrderDate.Year == 2005).
      Select(o => new { c.Name, o.OrderID, o.Total })
 
)

If we have learned anything from Java’s struggle with
object-relational mappers, it’s that embedding SQL in your code is usually a bad
idea, so I’m having a hard time seeing the point in furthering the practice by
making it a syntactic part of it.  I am predicting a very grim future for
this feature.

Object
Initializers:    B+

This feature
helps reduce the clutter of your classes by waiving the declaration of simple
constructors:

public class Point
{
int x; int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
Point p = new Point { X = 0, Y = 1 };

In this example,
Point declares two properties but does not include any constructor that accepts
either of these properties  Yet it is
possible to create a Point object and to initialize these properties in
one statement.  Quite a relief from the verbosity of this.name = name that
plagues Java.  Notice also how well this feature plays out with C#
properties (another top priority on my Java wish list).

Conclusion

There are so many new features in C# 3.0 that
statistically, you are guaranteed to hate at least half of them. 
Interestingly, feature excess has certainly not dampened the popularity of C++,
quite the contrary, so if Microsoft can guarantee that C# 3.0 will be completely
backward compatible with C# 2.0, I am predicting that it will have a great
future.   And a lot of detractors.