For the past couple of weeks I've been learning to use C# using .NET in Windows and Mono in SuSe Linux, and I have to say that I find the language rather annoying. I've never been a big fan of Java, and C# is certainly nicer to use than Java because the library calls aren't all 1000 characters long, but I find all the contrivances required to obfuscate pointers to be incredibly cumbersome.

Keywords like ref and out appear to be largely redundant, for example. Properties like get and set are cool (and remind me of Visual Basic), but if I build a class with a regular member variable and then later decide to change it to a property, I have to recompile everything that interfaces with that class; it'd sure be nice if that were transparent. Furthermore, what's with switch statement case labels not automatically falling through? Stupid. Plus, main() has to belong to an object, but then its cluged to work similarly to in C/C++!

Overall, C# has a lot of unintuitive features that translate messily from C/C++ and generally don't make life easier. I can see why they may make garbage collection and array bounds checking easier, but I don't care how hard those are to implement! I'd rather have a clean, elegant programming language that didn't feel so ad hoc.

8 Comments

I'm teetering on the edge of learning / having to learn C#. The little I already know about it looks forbidding. It doesn't look like an improvement over either C++ or Java. The aggressively hyped Microsoft publications about it do nothing to dispel my sense that it's a trap with no exits.

At this time, I feel that language development should more or less stop. There are already adequate languages for expressing the solution to any imaginable information-processing problem. Nor has any language "breakthrough" since the invention of C really done much to improve programmers' efficiency or the reliability of their work. So why build a new digital Tower of Babel, when so many of us are so relieved to have escaped from the previous one?

Wacky Hermit said:

Just out of curiosity, is the name of that language read "C sharp" (like the musical key) or "C pound" since that symbol is also the pound sign, or some other way that hasn't occurred to me?

Cypren said:

It's "C-sharp."

Speaking as someone who made the jump from C++ to C# about four years ago, the annoyances with the language do fade after a bit. (Of course, I've also done Java, and C# is a godsend in comparison.)

I do find that it's far, far easier to train junior developers to use C# than C++, though that's probably mostly a consequence of the .NET framework rather than the language. I've never yet worked in a shop where we were allowed to write managed C++ code, so I'm not entirely sure how C++.NET compares to the "real thing," or what its real differences from C# are (other than the little superficial things like array declarations), but you might find it more to your liking, Michael. (And you can compile it into otherwise-C# projects. The hard part is just getting management approval.)

Custom IT solutions are becoming more and more complex with the interconnection demanded by our modern information society. The ISV libraries which have sufficed for the last decade to reduce code duplication are looking much less attractive with the debut of monolithic code frameworks which include a vast amount of common functionality in a consistent, ordered structure.

Couple this with the fact that a managed environment prevents many of the most common, but hardest to find, mistakes that junior programmers (and even senior ones) can make (such as buffer overruns), and your personnel costs decrease as you can afford to let the compiler "verify" a lot of your code without strict human scrutiny. I don't think this produces good code, mind you -- but from a non-technical businessperson's standpoint (and let's face it -- we all know that a lot of businessmen view all techies as plug 'n play expendable), it sure looks attractive: a $45k guy right out of college can do the work you were paying a $70k guy to do before.

Like it or not, the majority of modern IT development is moving to managed platforms.

In areas such as embedded applications, managed code is still a waste of time; the hardware platform is fixed and resources are very limited, so an excellent programmer can do a much better job at tuning an optimizing than an automated system. However, JIT compilers and runtime optimization algorithms are becoming far more sophisticated, and the latest iterations of both the Sun JVM and the Microsoft CLR can produce highly optimized applications code that can easily outperform what an average -- or even a fairly good -- C++ programmer can write on the same system platform. This is making managed code a very attractive solution even for professional product companies developing marketable packages. Note that Microsoft already switched all their non-legacy application development to C# -- that wasn't just a marketing move.

At some point, of course, the overhead of the runtime environment will burden the application (especially for small, quickly-excuted code packages which need to load and unload modules constantly), but for most general uses, the optimization bar has been raised to where only a truly excellent developer can really justify writing an unmanaged solution for "performance reasons." (Although plenty use that canard anyway, not realizing that a side-by-side test would likely shame their code.)

I think there's going to be plenty of work around for C++ developers for a while, but more and more, it's becoming relegated to low-level systems development in places where you have to get very close to known hardware. For the higher level code, I think we're going to be living with a VM of some kind for the forseeable future.

Cypren said:

By the way, as to your specific complaints:

1.) ref and out exist to placate C programmers who aren't following proper object-oriented design. If you're writing methods that take these kind of parameters, you're doing something wrong. I really wish they'd left them out of the language entirely.

2.) Properties are just a user-friendly mask for functions, so when an assembly is compiled, property references in C# code are translated to function pointers in native form. That's why you have to recompile interfacing assemblies; the instruction in those assemblies exists to reference a memory location, not to call a function. Yes, this could be changed to a run-time check, but that would be an extraordinarily significant performance hit that can't even remotely be justified by the somewhat minor inconvenience of recompilation. Generally speaking, best-practice is to never have public variables on any exportable classes -- always use properties. (VS.NET 2005 has a nice tool for converting public vars to props, but in the current release, it just has to be written by hand.)

3.) I completely agree. Taking out the fall-through capability of switch was a dumb idea; I understand why they did it (the "protecting you from your own stupidity" philosophy), but man, I wish that was an optional compiler setting rather than a hard and fast rule. No more Duff's devices!

4.) main() has to belong to an object because *everything* has to belong to an object in a truly object-oriented environment. (Of course, C# isn't truly object-oriented, because it has primitives, but it's very close.) What do you mean that it's "kludged" to work like C/C++, though? How would you have preferred it be implemented?

FWP: Generally I agree, though as Cypren explains, with processor speed and memory size exploding, managed systems are probably the way coding is going to go.

Cypren: 1) But I like pointers! It's hard not to want to use them.

2) It does seem smart to only use properties instead of public variables, but it doesn't feel clean... it feels too fluffy. It would be nice to have a tool to generate the properties automatically.

3) Or allow it in unsafe code!

4) I would have preferred it if main() were a top-level global function, because that's how it's treated. Static member functions in general seem like cheating to me... everything should be tied to an instantiated object. Perhaps the program itself could be an implicit object, allowing functions and globals that are "outside" any other sub objects. Eh.

In general, I don't like special cases, and C# seems full of 'em. Still, I'm glad to be learning it, since it'll look good on my resume.

BTW, it looks like we're going to be doing C# development under vxWorks eventually, on embedded systems. I don't think anyone else is doing anything like that.

Cypren said:

I agree it's hard to stop using pointers once you've grown accustomed to them, but realize that you're programming in a proper object-oriented language now. Pointers do exist, but they're masked from you, and you're not supposed to think of them as such.

Any time you pass an Object-derived type to a function, you're actually passing a pointer to it. Modifications to that object inside the function will result in modifications to the object passed. So on that count, you can already consider all non-primitives to be passed as "ref" type.

However, more fundamentally, you should never rely on a function to modify the parameters given to it. If you need to return multiple pieces of information with a function call, the proper way to do it is to create a specialized container object to hold them. I understand that this seems like a lot of work to someone steeped in traditional procedural programming, but it does result in much cleaner, more coherent code, because other people examining your function don't need to scour it to find out how you've changed the calling parameters; they can rest assured that whatever needs to come out of the function is returned in its output.

This is also, by the way, why I highly recommend creating strongly-typed collections or arrays anytime you return multiple objects of a single type, rather than returning them in an ArrayList object or some other type-neutral container.

By the way, if you want a quicker way of creating properties on objects, use the VS.NET Class View tab. Right-click on the class, pick Add | Add Property, and a dialog box will come up prompting you for the name and type. It'll fill in the rest.

AP said:

Quoting :
C# Is Annoying
Michael Williams

C# is a RAD tool C/C++ are NOT!

ref & out are NOT redundant.Go look at the documentation to figure out why they are provided.

Neither C/C++ provide a
- default Thread class,
- Networking support
- a simple method Callback mechanism( besides interfaces)
- Support for building DLLs easily without getting into COM domain
- Easy to build & Debug UIs. Java comes nowhere close to windows UIs!

So before you go dissing on C#, go educate yourself!

AP said:

Not to mention garbage collection AKA shielding from pointers!.. thatz the whole purpose of a garbage collected language

Leave a comment

The comment login system is acting strange. If you get an error message saying you aren't logged in when you are, just reload the comment page and try again. I'm trying to track this bug down, but it's not easy.

Supporters

Email plasticATgmailDOTcom for text link and key word rates.

Site Info

Support