views:

176

answers:

2

I have used auto properties a lot but I have gone more and more away from that setting up classes with readonly backing fields initialized in the constructor. I remove all setters and only add the back if the property clearly need a setter.

I find this makes my classes more robust and elegant OO wise and I am kicking myself for not doing this earlier.

I find constructors are very underused generally in c# code examples and I think auto-properties and object initializer are a big part of this, so my question is why does the c# team push features like this and not is focusing more on deliver features pushing best practices more. Generally I think its too easy writing bad code and believe more could be done helping coders write good code

+5  A: 

From conversations, I believe the C# team understands that they've made it easier to write mutable types while not providing similar benefit for immutable types. It's not that they've made immutability any harder over time - they just haven't made it any easier... except for anonymous types, which are immutable, but have various other drawbacks. I certainly wouldn't wish automatic properties to be taken away - where they're appropriate, they're really useful. I'd just love to have the equivalent for readonly properties (allowing them to be set just in the constructor).

I've found that C# 4's named arguments and optional parameters have made it easier to construct immutable type instances though - you can still get many of the benefits of object initializers, without the mutability drawbacks. Simply provide default values for aspects of your type which are truly optional, leave the rest as mandatory constructor parameters, and the caller can do what they want - using named arguments to add clarity.

Collection initializers are a tougher nut to crack, unfortunately. I'd like to see "chained" initializers which could work with immutable collections, so that instead of repeatedly calling Add on the same instance, the compiler could create calls to Plus which chained together:

ImmutableList<string> x = new ImmutableList<string> { "a", "b", "c" };

would go to:

ImmutableList<string> x = new ImmutableList<string>().Plus("a")
                                                     .Plus("b")
                                                     .Plus"(c");

Of course, it would be nice to have more immutable collections in the framework to start with :)

None of this helps on the auto-props side, of course. I have to admit I've been cheating a certain amount recently, faking immutability using private setters:

public string Name { get; private set; }

It does make me feel dirty though, not making it truly immutable when that's my real intention.

Basically, I'm saying that I feel your pain - and I'm pretty sure the C# team does. Bear in mind they have limited resources though, and designing a language is darned hard.

You may find the videos from NDC 2010 interesting - there's a great panel discussion with Eric Lippert, Mads Torgersen, Neal Gafter (and me), and my proposals for C# 5 are in another video.

Jon Skeet
It would certainly be nice if immutability was made easier. To guarantee full immutability, you have to be completely in control of all the classes you contain. For example, you said that anonymous types are immutable, however I added an array and a mutable list to it, and was able to modify both of them. If you have a publicly accessible member that is immutable today, it can be made mutable tomorrow, and your immutability gets broken as a result.
Merlyn Morgan-Graham
Thx, I'll take a look at those videos. After reading some more it seems F# are dealing with these things in a nicer way, locking down objects by default and allowing mutability if the need is there. I guess legacy stops the c# team going in that direction. What are your thoughts about F# vs C# Jon?
TT
@TT: I haven't had as much experience as I'd like in F#, but I do like various things that F# does, certainly. Many of the suggestions I've made about C# 5 were based on F#.
Jon Skeet
I agree 100% with you on private setters. It's far too easy for me to go `propg`+`tab`+`tab` rather than creating a proper readonly backing field. Surly `public string Name { get; readonly set; }` (as bizarre as that sounds) will make it into C# 5?
Alex Humphrey
@Alex: That's exactly what I've proposed before now :) I don't know whether it'll get into C# 5 though. Hopefully we'll start to see the first bits in a little while.
Jon Skeet
A: 

I find constructors are very underused generally in c# code examples and I think auto-properties and object initializer are a big part of this

If your object has a lot of properties, you clearly don't want to initialize them all from the constructor. Having to pass more than, say, 4 or 5 parameters is pretty bad for readability (even though Intellisense makes it easy to write). Also, if you only want to initialize a few properties and use the default value for other properties, you either need many constructor overloads, or you have to pass these default values explicitly to the constructor.

In such cases object initializers are very handy, as long as the properties are not read-only (but as Jon pointed out, optional parameters in C# 4 are a good alternative)

why does the c# team push features like this and not is focusing more on deliver features pushing best practices more

I think object initializers were introduced because they were necessary for Linq: you couldn't create anonymous types without them. As for auto-properties, they're less vital, but it was probably easy to implement and it can be a real time saver for properties that do nothing more than encapsulating a field.

Thomas Levesque