c# constructors vs auto-properties and object initializers
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 constru开发者_开发百科ctor. 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
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.
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
I completely agree with you. I faced with legacy code where there are a lot of object initializers used for some class hierarchy. I needed to add some properties and then I got a headache with finding all places where class instances are constructed. First time I submitted to. And now I need to add one more property. This is crazy!
To restrict usage of object-initializers I deleted parameterless constructor.
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.
精彩评论