Does C# have too many language features?

我的未来我决定 提交于 2019-11-29 22:53:47
Marc Gravell

Yes, it is a risk - and it gets discussed a lot. It is getting to a point where it is very hard to pick up C# from scratch. Fortunately, things have stabilised a bit, and the language changes between C# 3.0 and C# 4.0 are relatively minor.

Actually, I've recently been doing a lot of work trying to fix a CF generics problem, and as part of the fix it might actually happen that the code reverts almost to C# 1.2 techniques (no, or very few, generics). So most problems can be addressed with the simpler language constructs. The point is: how hard should it be to do something?

For example - anonymous methods add a LOT of benefits for relatively little complexity. dynamic (4.0) adds some more for the COM interop scenarios. Iterator blocks are invaluable for LINQ-style code...

I see a lot of questions about the non-trivial parts of C#, and I think I would struggle to teach a beginner all of C# from the ground up. Books like Jon's C# in Depth are good for people who already know the basics (at least C# 1.2; ideally some C# 2.0) - but it is not really designed for newbies (I know Jon won't disagree).

A tricky one indeed. Fortunately, the C# team set the bar (for inclusion) very high; something new has be be very useful to make it into the language.

In my opinion, C# does not have too many features. Almost any of the fancy newer features from 2.0 and 3.0 is of every-day use to me and my co-workers, and even the VB guy quickly picked them all up. Some of the new features make learning the language even easier, like using inline lambdas instead of delegates and the var keyword and object initializers, just to name a few from C# 3.0 (there is no C# 3.5, by the way, you're confusing that with .NET 3.5).

C# has been made simple in most cases and the powerful features are all easy to use, unlike C++, where the designers say that you can do absolutely everything with C++, but they never mention that many things tend to become a real pain, which happens because C++ just can do really everything, including many things that most programmers will rarely, if ever, use. Supporting everything means that many things are more complicated than necessary, making it harder to learn. That's the difference between a language where features make it hard to learn, yet very powerful and a language where features make it easier to use and improve productivity, even though being less powerful in theory.

And, in pure number of features, C# is far away from C++, especially if you include C++0x in this picture, making it easier to learn despite having "too many features" for some people. My point with C++ was rather that C# doesn't really have so many features, if you want.

When I code in C#, I use virtually every feature of it. Not all at once, mind you, but every feature of C# has its place. A lot of people don't know that C# has a "::" operator and have never heard of "extern alias", but I had to use it today to resolve a naming conflict between two DLLs.

"Yield return" is one of my favorite features. I don't use it every day, but I used to write IEnumerator interfaces manually in C# 1.0 and that was a huge pain I'd rather not repeat. Besides, it's really useful for writing coroutines, even coroutines that don't produce any output (yield return null = pause the operation).

C# has inner functions and closures. When I code in C++, they are sorely missed.

It seems dumb that C# has so many different ways of writing an inner function,

  1. delegate(int x) { return x*x; }
  2. x => x*x
  3. (int x) => { return x*x; }

But #1 is only for historical reasons and forms 2 and 3 each have their place.

Whether it's extension methods, operator overloading, generics, generic constraints, default parameters, null coalescing, the ternary operator, static constructors, checked/unchecked, auto-properties, preprocessor directives, value types... as a full time programmer I use all of these at least occasionally, and eliminating any one of those features either creates extra work and aggravation for me (foo(x) ?? bar(y) now has to be written { var temp = foo(x); if (temp == null) temp = bar(y) }), or requires me to write fatter/slower code (e.g. if you replace value types with classes, some of my code would slow down and memory use would increase dramatically).

Far from having too many features, I think it doesn't have enough. Any time I have to write similar code over and over and over, I curse the language for not having any shortcut.

The trick is making it possible for programmers that don't work full time to understand. (as for those people that program in C# full time and still can't learn the language--um, fire them?) It might have helped if Microsoft had made features more "Googlable" or at least "F1-able". For example, when I put the cursor on "??" or "=>" and press F1, I should get a help page for those operators. Or consider static constructors: if the code said "static constructor()" instead of "static MyClassName()" then it would be easier to web-search for it.

IMO, a bigger problem than language bloat is framework bloat. The .NET framework is gigantic, with Microsoft reimplementing the same things repeatedly, making bloated, flawed designs each time: WinForms and WPF, the various ways of accessing a database, etc.

You probably should read this blog post by Eric Gunnerson, a member of the C# compiler team at Microsoft.

He explains how new features make there way into the language. Basically they get "-100 points" in the beginning, "which means that it has to have a significant net positive effect on the overall package for it to make it into the language."

There is actually a lot of debate on how C# should evolve. Indeed, some consider that by adding a lot of new features the language becomes to difficult to learn, but most view C# as a multi-paradigm programming language. It is first of all a strongly-typed full-featured object-oriented language, but it does have concepts that until recently were restricted to functional and dynamic programming languages. These features, though they might seem confusing for a beginner, offer a lot of flexibility and power, and sometimes they might prove enough to keep you from using a domain specific language in the application and dealing with all the integration issues. You can always talk about what should be implemented in the language itself and what should be part of the framework, but keep in mind that most of the features you mention and consider as superfluous are actually the result of the developers' requests, and they do provide functionality that sets C# apart from other languages (Java comes to mind). Once a programmer gets uses to these features, he will come to realize their advantages.

You mentioned Linq, and I have to admit I was a bit skeptical at first, since I have always considered SQL to be quite a natural language to work with data, but now I really like and I do see the advantage of having queries evaluated at compile time. Lambda expressions are always nice, indeed they can make the code hard to read if used excessively, but sometimes they actually simplify it. I'm not a big fan of the 'var' keyword but sometimes it does come in handy, and let's be honest not using it when writing Linq would make the code difficult to read. I'm a beginner programmer myself, and I don't think it is difficult to learn these concepts. I also use Java a lot in school, and I really miss some features of C# (I'm not saying that Java is a bad language, on the contrary, in some regards I think it is better than C# - code contracts, especially for academic purposes).

I don't think learning the new language features is the part to worry about: learning the right situations in which to apply them is what takes decades.

Sometimes they can hardly understand code that is written by people using all the new features.

This is the real problem that you need to address. A code base fractured into different styles and not maintainable by everyone is an expensive code base to maintain. Using novel features to write "short and nice code" may not maximise the utility of that code for your organisation.

What's the root cause of your situation? Is it:

  • Some programmers don't understand the new features
  • New features have been used inappropriately
  • New features have been used to hack around design flaws (often the case with reflection)

I would bet money it will be a mixture of the above.

Should it be hard to learn a modern programming language?

For: you ideally want to use the most powerful language you can, that lets you express things correctly.

Against: you want to be thinking about the problem at hand rather than about how the language works.

Overall: I am for more powerful languages, even if they are more difficult. I find myself irritated when I can't make the language do what I need, so I have to work around it or turn it into yet another stupid pattern. I don't particularly mind running up against some weird new syntax, because the internet is only a click away.

Edited extra thought: I am for trying to maintain consistent/logical syntax when adding features to the language, but this is not the right thread for a lisp discussion.

Are there features that C# should get rid of?

I make a lot of use of the new features like LINQ, extensions methods, var (I just wrote out the type, why am I writing it again?) and anonymous functions. I have found they can give some pretty big productivity benefits. I would recommend to anyone who hasn't got to grips with LINQ yet that they take some time to learn Linq-to-Objects, because it is extremely convenient any time you have set logic to deal with.

I don't particularly like the special SQL-like LINQ syntax though. I find it a bit jarring in the middle of C# code - to my mind it clashes with the object method calling syntax style. I would be happier with the more common list comprehension syntax such as is used in e.g. Python.

Are there new features that C# needs?

I would really like some better syntax for quickly initializing arrays (or maybe IEnumerables?) and dictionaries. C# is a bit unwieldy in this regard - I end up having to type out so many braces. Related to this, I really miss the yield! (yield every item in this collection) syntax.

I would also like C# to borrow F#'s improved type inference and perhaps its tuples and multiple assignment. Maybe I should just go and use F#.

Eventhough I'm only a casual C# user; with strong background in Delphi, C++, and Python; I can grasp C# features concept quite easily. C# is a properly balanced language in my opinion. The only annoyance is that I could hardly remember enough syntax (especially Linq-related) in my head to produce code in touch typing speed like I can in Python. My preference toward pascal syntax could also impeding me. However, with help from the almighty Visual Studio.NET Express, this is not a problem at all.

As long as they provide such an amazing tool for free, I believe C# with VS.NET is among the best coding environments available.

I too like most of the new features and quite honestly wouldn't want to lose extension methods and linq in general.

As far as ease-of-learning goes, I think the issue is more a problem for new starters - and from experience, getting them up to speed is definitely a case of selecting the biggest wins and helping them out when they stumble onto something else. Aside from multi-threading, understanding generics seems to be key to getting the benefit of the other features.

Each additional feature does definitely bring additional benefits. Eventually new languages will come along that make those same features easier to use, but that doesn't in any way mean we shouldn't try to improve the ones we have now.

Yes C# has a lot of features but that's why we use it! Anyone entering into a career as a programmer should expect to spend there career studying / learning new things and taking exams! As someone who loves learning new things, thats why we love it!

Personally, I find lambda expressions and extension methods for example, extremely useful. For creating larger scale distributed applications where I want to seperate data and logic I have found LINQ not to be so useful. But I look forward to c# 4 features such as optional parameters.

As @Alex mentioned, I think learning when to use features apropriately is the most challenging aspect. Horrah for those of us who have been with C# since the early days!

I think the problem lies with the people who just have to use the newest syntax for everything, everywhere. They make a simple 'Hello World' program would look like an explosion at a spaghetti factory.

Imagine you are a writer and you insist on using the most complicated, obfuscated, rarely needed or understood words all the time.

Not many people are going to read your books.

The fact that the language lets some people make such a mess drags other people down because they have to figure out what the heck is going on. My experience is that people who write code like this don't write code that works very well and needs a lot of maintenance. I mean they have already thrown the KISS principle in the trash. IMHO the art or programming is making complicated things simple not vice versa. This kind of situation may create a market for a simpler language that does everything you need it to do but in readable, human syntax only.

The features are the reason we use C# and what make C# 'modern'. If C# didn't offer classes for example - or multi threading for that matter, would anyone use that? Assembly is an example of a language that really has no features. It's silly easy to learn as a language but no one wants to use it.

The small domain specific languages are really an extreme on this. Take the classic regular expression for example. It got a HEAP of features just for string manipulation. If it didn't have these, who would use it? These features are what make it so powerful and expressive. Same with more general languages.

It's not like all of these features are required for writing C#. Understanding C# code is where the problems appear. But if these were not features in C#, everyone would implement multi threading in their own way and instead of learning the one way to deal with multi threading, you'd need to learn several depending on the code you are reading.

Yes , C# do has lot of features , and it is not my opinion , this is a fact, this is a rich platform. If anyone want to argue about that and claim that this language doesn't have lot of features , please show me a language that do have lot of features and explain why it has so much more features then C#.

Anyway, I don't see any problem with it. You can always chose the subset of the features that appropriate to you and use them. there is nothing wrong with a language rich of features , as long as the features are used correctly and not enforced to the code only because they exist.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!