views:

498

answers:

9

A number of features were introduced into C# 3.0 which made me uneasy, such as object initializers, extension methods and implicitly typed variables. Now in C# 4.0 with things like the dynamic keyword I'm getting even more concerned.

I know that each of these features CAN be used in appropriate ways BUT in my view they make it easier for developers to make bad coding decisions and therefore write worse code. It seems to me that Microsoft are trying to win market share by making the coding easy and undemanding. Personally I prefer a language that is rigorous and places more demands on my coding standards and forces me to structure things in an OOP way.

Here are a few examples of my concerns for the features mentioned above:

Object constructors can do important logic that is not exposed to the consumer. This is in the control of the object developer. Object initializers take this control away and allow the consumer to make the decisions about which fields to initialize.

EDIT: I had not appreciated that you can mix constructor and initializer (my bad) but this starts to look messy to my mind and so I am still not convinced it is a step forward.

Allowing developers to extend built-in types using extension methods allows all and sundry to start adding their favourite pet methods to the string class, which can end up with a bewildering array of options, or requires more policing of coding standards to weed these out.

Allowing implicitly typed variables allows quick and dirty programming instead or properly OOP approaches, which can quickly become an unmanageable mess of vars all over your application.

Are my worries justified?

A: 

Object initializers are just fancy syntax. There is nothing the developer can do with them that he couldn't already do before - they do however save you a few lines of code.

If by "extend built in types" you mean extension methods - again, this is nothing new, just better syntax. The methods are static methods that appear as if they were members. The build in classes remain untouched.

Implicit typed variables are needed for Linq. I also use them with generics that have a lot of type parameters. But I'd agree that I wouldn't like to see them used exclusively.

Of course every feature can be abused but I think that these new features actually let you write code that is easier to read.

chris
+4  A: 

Object initializers simply allow the client to set properties immediately after construction, no control is relinquished as the caller must still ensure all of the constructor arguments are satisfied.

Personally I feel they add very little:

Person p1 = new Person("Fred");
p1.Age = 30;
p1.Height = 123;

Person p2 = new Person("Fred")
{
    Age = 30;
    Height = 123;
};

I know a lot of people dislike the 'var' keyword. I can understand why as it is an openly inviting abuse, but I do not mind it providing the type is blindingly obvious:

var p1 = new Person("Fred");
Person p2 = GetPerson();

In the second line above, the type is not obvious, despite the method name. I would use the type in this case.

Extension methods -- I would use very sparingly but they are very useful for extending the .NET types with convenience methods, especially IEnumerable, ICollection and String. String.IsNullOrEmpty() as an extension method is very nice, as it can be called on null references.

I do not think you need to worry, good developers will always use their tools with respect and bad developers will always find ways to misue their tools: limiting the toolset will not solve this problem.

Paul Ruane
Well explained - +1
ChrisF
Thanks for the pointer on constructor initializer combination, question updated based on this.
Rob West
No probs. I believe the object initializers were added for anonymous types where one cannot specify a constructor because the type has no name! I've idea why the C++ ilk langs still insist on cstrs with name == to class name: an initialiser method called Initialize(), like Ruby, would be better IMO.
Paul Ruane
Actually, You are quite wrong about Object initializers. There is a big difference: in your first "old" style example, each assignment will be treated as an atomic operation, potentially leading for a time window that the state of your object is not consistent. "New" syntax will evaluate together
ArielBH
I have looked in Reflector. In the OI case (p1), the instance is assigned to a temporary var during init, before being placed into p1. So, yes, you are correct that using OIs does delay assignment until init is complete. It does not appear to protect in the multi-threaded environment though.
Paul Ruane
nice on the String.IsNullOrEmpty() I had assumed string s = null; s.IsNullOrEmpty(); would throw. Nice to know. +1
David Waters
I rather like object initialisers. They alleviate the need for 23 ctors that differ only in what gets non-default initialisation.
Peter Wone
@Peter: one can rely on properties for non-mandatory initialisation: see the first code example above.
Paul Ruane
+2  A: 

You could limit the features of C# 3.0 your developers can use by writing the restrictions into your coding standards. Then when code is reviewed prior to check in, any code that breaches these rules should be spotted and the check in refused. One such case could well be extension methods.

Obviously, your developers will want to use the new features - all developers do. However, if you've got good, well documented reasons why they shouldn't be used, good developers will follow them. You should also be open to revising these rules as new information comes to light.

With VS 2008 you can specify which version of .NET you want to target (Right click over the solution and select Properties > Application). If you limit yourself to .NET 2.0 then you won't get any of the new features in .NET 3.5. Obviously this doesn't help if you want to use some of the features.

However, I think your fears over vars are unwarranted. C# is still as strongly typed as ever. Declaring something as var simply tells the compiler to pick the best type for this variable. The variable can't change type it's always an int or Person or whatever. Personally I follow the same rules as Paul Ruane; if the type is clear from the syntax then use a var; if not name the type explicitly.

ChrisF
I wouldn't be interested in working for a company who'd introduce taboo on new features since it is equivalent of working with an old technology and you won't be extending your skills and experience.
User
Although I sympathize in principle here, in the business world, I wouldn't say that C# 2.0 (for example) is exactly an "old technology." If they were writing new software in COBOL I might agree.
mquander
@SO Troll - All I'm pointing out is that you can limit what developers can do. For example, you might not be able to install .NET 3.5 on the server.
ChrisF
I will hand in my notice the day they will make me use a restricted subset of otherwise available tools. I get paid (amongst many other things) to decide which language construct fits well the given situation. You can't micromanage programmers like that because they will be unhappy and will leave.
DrJokepu
A: 

One big mitigating factor about var is that it can never move between scopes. It can not be a return type or a parameter type. This makes it far safer in my mind, as it is always tightly typed and always implementation detail of one method.

David Waters
You're thinking of anonymous types, var just does implicit typing.
Adam Lassek
"variables that are declared at method scope can have an implicit type var" http://msdn.microsoft.com/en-us/library/bb383973.aspx . var can only be method local variables, not class level members or return type or parameter type.
David Waters
A: 

New features was introduced because Microsoft realized that they are absolutely necessary for implementing new language features. Like LINQ, for example. So you can use the same strategy: 1) know about those features, 2) do not use until you'd find it absolutely necessary for you.

If you really understand those features, I bet you'd feel it necessary pretty soon. :)

XOR
I fully realise that much of the new stuff in C# 3 was driven by LINQ, as I said I know each feature has its proper uses, my point is that added together all of these changes are having a negative effect on the language.
Rob West
IMHO, if you would look at the number of programs written in any language, you would find all different sorts of misuse. :) Of course, some languages are easier to misuse. Like Perl. I'm an architecture geek, so I think every developer should think about this first.
XOR
+2  A: 

I have seen your position expressed like this:

Build a development environment that any fool can use and what you get is many fools developing.

This is very true, but the rest of us look good by contrast. I regard this as a good thing. One of the funniest postings I have ever seen remarked that

VB should not be underestimated. It is an extremely powerful tool for keeping idiots out of this [C++] newsgroup.

More seriously, whether or not a tools is dangerous depends on the wisdom of the wielder. the only way you can prevent folly is to prevent action. foreach looks innocuous but you can't even remove items as you iterate a collection because removing an item invalidates the iterator. You end up dumping them in favour of a classic for loop.

Peter Wone
+1  A: 

I think the only really justified issue in your bunch is overuse of extension methods. When important functionality is only accessible through extension methods, sometimes it's hard for everyone in a group to find out about and use that functionality.

Worrying about object initializers and the "var" keyword seems very nitpicky. Both are simple and predictable syntax that can be used to make code more readable, and it's not clear to me how you see them being "abused."

I suggest you address concerns like this through written, agreed-upon coding standards. If nobody can come up with good reasons to use new language features, then there's no need to use them, after all.

mquander
A: 

Are my worries justified?

No. This has been another edition of simple answers to simple questions.

Joel Mueller
Vote me down if you want, I know it was a flippant answer. But the question was whether his worries were backed up with adequate justification, and in my honest opinion, no they weren't. I mean, why leave out the classic, "properties are just syntactic sugar == bad code" complaint?
Joel Mueller
A: 

At least with "var" and intializers you're not really able to do anything new, it's just a new way to write things. Although it does look like object initializers compile to slightly different IL.

One angle that really blows my mind about extension methods is that you can put them on an interface. That means a class can inherit concrete code by implementing an interface. And since a class can implement multiple interfaces that means, in a roundabout sort of way, that C# now has something like multiple inheritance. So that's a new feature that should definitely be handled with care.

Barry Fandango