Wednesday, April 25, 2007

C# 3.0: The Sweet and Sour of Syntactic Sugar

I’ve just started reading the blog of Scott Guthrie who is a general manager at Microsoft and is currently writing about the new C# 3.0 (code named Orcas). The post I felt strongly about describes three new language features including:

  • Automatic Properties
  • Object Initializers, and
  • Collection Initializers

All three features are purely syntactic sugar: they add nothing of real value to the language (unlike generics in C# 2.0 for example). One feature is wonderful, while two are terrible.

The Sweetest Syntactic Sugar Ever

Automatic properties are fabulous. I’ve always grumbled about the number of lines required to create simple properties. Anything that can turn:

public class Person {
    private string _firstName;

    public string FirstName {
        get { return _firstName; }
        set { _firstName = value; }
    }
}

Into:

public class Person {
    public string FirstName { get; set; }
}
Gets my vote.

Sickeningly Sweet

Perhaps I’m a purest, but with more language conveniences comes: a steeper learning curve because of a larger language, and decreased readability because of the numerous ways of doing the same thing. Picture reading this in someone else’s code:

Person p = new Person("Lee", "Richardson") {
    Phone = "111-111-1111",
    Age = 29,
    Company = new Company("Near Infinity") {
        Phone = "222-222-2222"
    }
}

Who would write this crap? Everyone else, now that Microsoft lets them. I vote for the verbose, the readable, the single approach:

Company company = new Company("Near Infinity");
company.Phone = "222-222-2222";

Person person = new Person("Lee", "Richardson");
person.Phone = "111-111-1111";
person.Age = 29;
person.Company = company;

Hmmm, and by the way did you count the number of lines?

Conclusion

So do the differences between my thoughts on automatic properties contradict with my thoughts on object initializers and collection initializers? They don’t. Basically a little sugar is good, but too much ruins the dish.

11 comments:

Anonymous said...

Hi Lee,

One post you might want to check out is my one on LINQ Query Syntax: http://weblogs.asp.net/scottgu/archive/2007/04/21/new-orcas-language-feature-query-syntax.aspx

It shows a good use for object initializers (which you didn't like above). It provides a really elegant way to "shape" the results of a LINQ query (and allow ORM data mappers to efficiently grab only the data from a database that is needed as a result).

Hope this helps,

Scott

Mike said...

Reg had something different to say about the same type of syntax:
http://weblog.raganwald.com/2007/04/rails-style-creators-in-java-or-how-i.html

Not the same language, but the principle is the same. He makes good arguments for that style.

John said...

Thank goodness Mike jumped in and posted that link. I would have wracked my brain for a couple of hours trying to remember where I saw that.

Lee Richardson said...

I very much appreciate the debate and hearing different points of view on the topic.

Regarding Scott's post, I'm honored you (he) would post on my humble Blog. I am looking forward to reading the LINQ post, not quite enough time at present; will read and comment later.

Mike & John, thank you very much for the link. I actually found the argument in the article compelling. Basically the object initializer and collection initializer syntax groups and *forces* a section of code to be used exclusively for initialization.

I also now realize this is what Seth Schroeder was referring to when he said the syntax provides more structure. That was a comment on my double-posted company blog at:

http://www.nearinfinity.com/blogs/page/lrichard?entry=c_3_0_the_sweet

I still don't buy the arguments of reducing number of lines or eliminating retyping of variable names (that's what intellisence is for), but I sure do like structure in code.

And who knows, perhaps with the addition of reading the LINQ post I will be a complete convert.

Anonymous said...

HARHAR, please tell me why you use getters and setters with simply returning and writing the values from the outside to the member var. When you want that you can simply make that property public!

Anonymous said...

And where is the "Collection Initializers" example?

Lee Richardson said...

Re: anonymous on April 28:

The answer to your question is in Scott Guthrie's original post. Rather than restate I'll just quote him:

"There are a lot of downsides to exposing public fields. Two of the big problems are: 1) you can't easily databind against fields, and 2) if you expose public fields from your classes you can't later change them to properties (for example: to add validation logic to the setters) without recompiling any assemblies compiled against the old class."

Lee Richardson said...

Re: Anonymous on May 2:

Good point. In my mind the two are so similar I figured no one would mind. For completeness here's the example from Guthrie:

List<Person> people = new List<Person> {
    new Person { FirstName = "Scott", LastName = "Guthrie", Age = 32 },
    new Person { FirstName = "Bill", LastName = "Gates", Age = 50 },
    new Person { FirstName = "Susanne", LastName = "Guthrie", Age = 32 }
};

That code combines collection initializers and object initializers. I just think that will be extremely ugly once you initialize those Person objects as in my example, but I do now recognize the benefit of additional structure.

Alberto Acosta said...

i will say .net 3.5 rather than 3.0 that is just .net 2.0 + wcf + wpf + wf + cs

Anonymous said...

> HARHAR, please tell me why you use getters and setters with simply returning and writing the values from the outside to the member var. When you want that you can simply make that property public!

You need to use properties for databinding.

But, if you are doing databinding, you probably have to decorate the setter anyway and not use this syntax.

ithinkyoureatool said...

you're a tool