.net Development
I had a Mac for a while. It didn’t really work for me, but I take the chacun a sont gout view of these things. If you like using a Mac and OSX, be my guest.
What I object to is some of the bull that’s written about Windows (or Linux).
There’s an article on ArsTechnica by a developer who switched from Windows to Cocoa development.In part 2, he decided to take on .net.
After a whole lot of wild, stupid, and frankly biased nonsense about the types of developers (only people who write packaged software for themselves count), he tries his hands at some facts:-
.NET isn’t like that. Although .NET can call C APIs (just like everything else can), the real objective is for all programming to reside in the .NET world. .NET is meant to be the entire platform, with all the different languages that people use living inside the .NET environment.
All programming? That’s why Visual Studio 2008 still compiles C++ for Win32?
This is why .NET has APIs for tasks like reading and writing files; in the .NET world you’re not meant to use Win32 to do these things, you’re meant to use .NET’s facilities for doing them.
Firstly, it’s a lot easier using .net’s facilities, and secondly, it’s better because it’s managed code.
Because everything now has to live “within” the .NET world, .NET has to be all things to all people. Well actually, that’s not true. It’s trying to be good enough for the first and second kind of programmer. The third type—well, just ignore them. They’re too demanding anyway.
The thing is that the first 2 groups are also demanding. It’s just a question of how you determine “demanding”. I build database driven websites and applications, and I’ve thrown a lot at .net, and it’s always delivered for me. So, from my perspective, I demanded and it delivered.
If you’re going to do 3d rendering, games development or write a search engine, you probably don’t want .net. You don’t want the overhead of managed code, and can probably afford the overhead of writing unmanaged code. But that’s a tiny proportion of the software development world.
But for data processing .net and vs.net just make your life easy. It makes you more productive. It means that instead of wasting your time hunting down memory leaks and sorting out pointers, you’re writing business logic and giving more value to your customers.
The .NET library is simple to the point of being totally dumbed down; it’s probably okay for the first and second groups, not least because they don’t know any better, but for the rest it’s an exercise in frustration. This frustration is exacerbated when it’s compared to .NET’s big competitor, Java. Java is no panacea; it too is aiming roughly at the middle kind of developer, which is understandable, as they’re the most numerous. But Java’s much more high-minded. It’s much stronger on concepts, making it easier to learn.
Such as? Oh no, he doesn’t say. “Dumbed down”? What the hell? Is the author suggesting there’s things that .net can’t do that Java can, because I’ve yet to find something. Maybe he means that .net just makes life easier.
There’s actually a lot in common between the two. Where there are differences, I’d not call either “wrong”, just “different”.
For example, .NET provides an API named Windows Forms for writing GUIs. Windows Forms is based heavily on the Win32 GUI APIs; the same GUI APIs that owe their design to Win16. To properly write Windows Forms programs, you need to know how Win32 works, because there are concepts from Win32 that make their presence felt in Windows Forms.
He’s talking about threads, and as someone who came from somewhere other than Win32, I picked up threads in a few hours. It’s not exactly a tricky concept.
There’s a way to test whether an update to a window needs to be sent to the thread that actually owns the window or not, along with a mechanism for sending the update to the window’s thread. Except this way doesn’t always work. Under some situations, it can tell you that you’re using the correct thread already even if you’re not. If the program then carries on and tries to perform the update, it may succeed or it may hang or crash the application.
Never had this, and never heard of this before. The author could have linked to some code that showed this…
These little issues are abundant. The .NET library does work. It more or less has all the main pieces you need, but it’s full of areas where you have to deal, directly or indirectly, with the obsolescent mediocrity of Win32.
I’d disagree with that. OK, it probably wraps some Win32 concepts, but it abstracts the heavy lifting. The only way to make .net concepts simpler would be to lose overall functionality.
If Win32 was a mess and .NET didn’t fix it, the other opportunity MS could have had was to fix it for Win64, the 64-bit Windows API. Porting a program to Win64 requires a recompile at the very least, and it can often require code changes to avoid doing things that are safe for 32-bit processors but not for their 64-bit brethren. Because of this necessary recompile, one would think that MS could surely have tidied things up a bit. Maybe not radically overhauled, but tidied up.
Why? Why would you want working functions removed so that you’d have to change your code to make it work? Backwards compatibility is what businesses that use .net, and even companies that build package software, want. Obviously, we want to use better functions, but we also want the luxury of not being forced to swap over.
I’ll give you a reason why: Photoshop CS4 64-bit. Windows is getting it, Mac OSX isn’t. The reason is that Photoshop is written in Carbon, and Apple decided at WWDC2007 to drop Carbon 64 (having a year earlier told developers that it would happen in Leopard). Which means a huge amount of rework to make it work with Cocoa.
Now, Microsoft annoyed a lot of VB6 developers when they brought in .net. They lost a lot of skills, and companies with VB had to consider their options. But at least they had a routemap that could be described as sensible. Microsoft made it clear to developers what would happen when they announced .net in 2002, and vb6 ended official support in March 2008. I’d prefer Microsoft kept supporting vb6, but 6 years isn’t too bad. Developers had plenty of notice.
While code deprecation can leave a lot of stuff lying around, it’s also what gives developers stability.
So Windows is just a disaster to write programs for. It’s miserable. It’s quite nice if you want to use the same techniques you learned 15 years ago and not bother to change how you do, well, anything, but for anyone else it’s all pain.
What’s the advantages of changing? Change should be about progress.
I thought before that Microsoft cared about people like me. But it doesn’t. And it makes programming on Windows painful. Microsoft is great at backwards compatibility—you can take really old programs and compile and run them on a brand new Windows—but terrible at design and terrible at providing a good experience.
I’ll gladly stick the knife into Microsoft where I see fit. Frontpage is horrible, Vista is a massive disappointment, they play fast and loose with standards. But if there’s one area where they are above the rest, it’s in development tools and environment. I’ve tried Eclipse, and it’s good, but it’s not a patch on VS.NET. I’ve seen XCode, and it’s not even close.
There’s a lot of software for Windows, a lot of business-critical software, that’s not maintained any more. And that software is usually buggy. It passes bad parameters to API calls, uses memory that it has released, assumes that files live in particular hardcoded locations, all sorts of things that it shouldn’t do.
True. What the hell’s that got to do with Microsoft? I would say the same thing about Mac, but I’ve never heard of anyone doing data processing on Mac (I suppose Apple do).
Microsoft has all sorts of special behaviours it needs to preserve. This means that not only can it not make the API better—it can’t even easily make the API’s implementation better. It’s all too fragile.
Huh? Supporting old API calls means you can’t write new and improved ones? Since when?
There might not be as much third-party software for Mac OS X as there is for Windows (a pleasing operating environment can only do so much to mitigate a 3 percent market share), but the quality of the applications is a great deal better.
Such as? He doesn’t say.
Third-party developers on Mac OS X strive to make applications that work in a way that’s consistent with the OS itself, with first-party applications, and even with each other.
Like Windows? Microsoft long ago published a set of UI guidelines that many developers follow.
Regular updates to the OS keep developers on the upgrade treadmill; they work to make their applications fit in with the latest and greatest release, leveraging whatever new bells and whistles it provides, further improving the software ecosystem.
Like Adobe with Photoshop CS4 64-bit?
The UI guidelines certainly have the right idea. But they then get ignored. They get ignored by Vista itself. They get ignored by Microsoft’s flagship applications like Office. They get ignored by third parties.
Wow. Third parties ignore the UI guidelines. Bad Microsoft. Bad!
Recognizing the gap in functionality here, a third-party developer produced its own ribbon-like object that developers could embed into their programs to gain a ribbon user interface. Microsoft in turn bought the third-party object and is now distributing it to developers using the current version of Visual C++. Oh, yeah—it’s only for C++ developers. No ribbon for .NET developers.
Yeah. There’s only about 5 different ones to download off the net, each with source code.
So where does that leave me? I want to write nice applications. I want to be able to concentrate on my own code rather than fighting the API the whole time. I want my applications to fit in with the OS and work in a way that’s consistent with first-party applications and even other third-party programs. I want this because I think it leads to better software; it means I can spend my time creating innovative and useful software that people enjoy using. I really want to do this, but you know what? On Windows it’s just too damn hard.
Nonsense. .net’s very straightforward, and fast enough. Paint.net is almost entirely C# (except for some graphics filters that are written in C++) .Unless you’re doing something processor intensive, or writing something low level (like drivers) you don’t need anything else on Windows.
Ars is generally better than material like this. I’d be interested in a genuine side-by-side comparison, an article showing what they feel are the advantages of Cocoa over .net from an informed position. Convince people why it’s better by using real facts rather than this rubbish.
“If you’re going to do 3d rendering, games development or write a search engine, you probably don’t want .net. You don’t want the overhead of managed code, and can probably afford the overhead of writing unmanaged code. But that’s a tiny proportion of the software development world.”
Actually, the thing is, it’s not “the overhead of managed code” that’s the problem. The “overhead” of managed code is–in a decent VM implementation–pretty small. Java has some pretty damn speedy JVMs, and the .NET runtime isn’t bad either (though it’s not as advanced as the JVMs when it comes to e.g. profile-guided recompilation, escape analysis). Really, it’s not the “managed” bit that makes writing these things suboptimal.
“But for data processing .net and vs.net just make your life easy. It makes you more productive. It means that instead of wasting your time hunting down memory leaks and sorting out pointers, you’re writing business logic and giving more value to your customers.”
That’s really the problem I have with .NET; I still have to waste my time with “the infrastructure” and not writing “my program”.
“Such as? Oh no, he doesn’t say. “Dumbed down”? What the hell? Is the author suggesting there’s things that .net can’t do that Java can, because I’ve yet to find something. Maybe he means that .net just makes life easier.”
Java makes it a great deal easier to program against interfaces. Java has useful, usable interfaces for e.g. cryptography, databases, collections classes; .NET by and large does not. This means, for example, that when writing .NET database code, it’s desperately tempting to use System.Data.SqlClient, because the vendor-neutral interfaces are so annoying. Moreover, in Java I can use e.g. PreparedStatements in the same way across multiple vendors; with .NET I can’t really do that because .NET doesn’t normalize the way parameters are passed. For Oracle it’s “:name”; for SQL Server it’s “@name”, for OLE DB it’s “?”. The weakness of the interfaces is pretty pervasive across the library.
Java makes a lot of things more pluggable; I can plug in crypto providers, socket factories, name resolvers, XML libraries, etc.. I can’t in .NET.
“Never had this, and never heard of this before. The author could have linked to some code that showed this…”
InvokeRequired returns false if IsHandleCreated returns false; however, in so doing it does NOT mean than an invoke is not required; it means that you should not call anything that sends a message to the wndproc *at all*.
“I’d disagree with that. OK, it probably wraps some Win32 concepts, but it abstracts the heavy lifting. The only way to make .net concepts simpler would be to lose overall functionality.”
WinForms is particularly bad; it exposes the WndProc, it exposes the HWND, it exposes window messages (including the vagaries of which order Windows sends them in), and as a result it doesn’t abstract anything like enough. But we see this all over the place; there are loads of things in the System namespace that are totally Win32-specific. Some examples are:
System.Cryptography
System.Management.*
System.EnterpriseServices.*
System.IO.IsolatedStorage
System.Security.AccessControl
System.ServiceProcess
System.Transactions
System.Windows.Forms.*
System.Windows.Ink.*
System.Speech.*
System.Web.Mail
System.DirectoryServices
System.Data.SqlClient/OleDb
Even classes in namespaces that are less Windows-specific, you still find lots of things leaking through. Particularly objectionable examples include System.IO.FileStream.Handle/SafeFileHandle, System.Net.Sockets.Socket.UseOnlyOverlappedIO/IOControl, System.Net.Sockets.SocketException.ErrorCode, and plenty more besides. There really is a lot of Win32 on display in .NET, and it’s to its detriment.
“Why? Why would you want working functions removed so that you’d have to change your code to make it work?”
To provide a cleaner, simpler, better-designed API to write programs for.
“Backwards compatibility is what businesses that use .net, and even companies that build package software, want. Obviously, we want to use better functions, but we also want the luxury of not being forced to swap over.”
We can’t actually have both. Supporting old decisions makes adding new mechanisms and features much, much harder, and sometimes outright prohibits it.
“What’s the advantages of changing? Change should be about progress.”
We can’t make progress whilst MS is stuck supporting decades old programs.
“I’ll gladly stick the knife into Microsoft where I see fit. Frontpage is horrible, Vista is a massive disappointment, they play fast and loose with standards. But if there’s one area where they are above the rest, it’s in development tools and environment. I’ve tried Eclipse, and it’s good, but it’s not a patch on VS.NET. I’ve seen XCode, and it’s not even close.”
… until you want to (say) profile your application, or design a UI, at which point Apple’s tools beat Microsoft’s hands down.
“Huh? Supporting old API calls means you can’t write new and improved ones? Since when?”
Raymond Chen outlines the concerns here: http://blogs.msdn.com/oldnewthing/archive/2007/07/23/4003873.aspx
“Like Windows? Microsoft long ago published a set of UI guidelines that many developers follow.”
Do they? Do they really follow them? Even MS doesn’t follow the guidelines. The newest set of UI guidelines (the Vista ones) are not followed by MS’s flagship application (Office 2007) or by Vista itself.
“Wow. Third parties ignore the UI guidelines. Bad Microsoft. Bad!”
If MS won’t follow its own guidelines, why should anyone else give a damn?
“Yeah. There’s only about 5 different ones to download off the net, each with source code.”
None of which works the same as the Office 2007 one.
“Nonsense. .net’s very straightforward, and fast enough. Paint.net is almost entirely C# (except for some graphics filters that are written in C++)”
Actually, Paint.NET is (arguably) almost entirely GDI+, which is written in C and C++, and which has managed code wrappers.
“Unless you’re doing something processor intensive, or writing something low level (like drivers) you don’t need anything else on Windows.”
Oh yeah? So if you want to talk to DirectShow or the brand new Media Foundation, you don’t need native code? News to me. News to Microsoft. If you want to use the new transactional NTFS, you don’t need native code (or P/Invoke)? If you want to use the new MS-supported MFC ribbon control, you don’t need native code? Or the upcoming Windows Seven ribbon control? If you want to use the new DWM APIs, you don’t need native code or P/Invoke? News to me. .NET is really very incomplete when compared to Win32. There are big bits of Windows just not available natively in .NET.
Dr Pizza,
1) I’m not advocating .net over java. Java’s fine.
2) What problems are you having with .net and “the infrastructure”? I build web applications, and it works just fine for me.
3) .net has collection and cryptography classes. It’s fine for XML.
4) In the end, how far off the mapping can you? If the underlying concepts are sound in Win32 (or Microsoft think they are) it’s likely that they’ll think they are for .net.
5) Cleaner, simpler APIs is nice. Given the choice between my legacy code working or having to change it, I’ll choose working and spend the money elsewhere.
6) “… until you want to (say) profile your application, or design a UI, at which point Apple’s tools beat Microsoft’s hands down.”. Maybe. Can I take a class that I’m using for a desktop app in objective-c and use it in a built and tested web framework which includes state, session and postback management? Can I add reference to a web service in with the simplicity of vs.net? I’ll trade all of that for a UI designer (what’s wrong with the one in vs.net?)
7) “None of which works the same as the Office 2007 one.”. As I didn’t name where the code was, I’ll call bullshit on this comment.
9) OK. I was a little oversimplistic. But if you’re working in the vast majority of the software industry, data processing, you don’t need to do those things either.
2) What problems are you having with .net and “the infrastructure”? I build web applications, and it works just fine for me.
A big black mark is that I can’t program against interfaces, because the interfaces either don’t exist (e.g. no ISet) or just don’t have enough functionality (e.g. no equivalent to C++ iterators, so I have to program against LinkedList directly).
I also persistently find that if a .NET class cannot do what I want then I have to just discard it completely in favour of my own code. For example, I wanted to write some code that sent and received e-mail over a variety of transports. There’s System.Net.Mail, but I can’t use the things in there (e.g. MailMessage) even if they’d be useful to me, because the method to serialize the MailMessage is marked as internal; only MS’s classes can use it. So I have to reinvent the entire thing from scratch. This just isn’t a very satisfactory situation, and it’s not a problem I’ve found in Java. Java seems much more extensible in this sense.
“3) .net has collection and cryptography classes. It’s fine for XML.”
The .NET collections are terrible. I didn’t say .NET didn’t have crypto or XML; I said it’s not pluggable. And it isn’t. .NET’s crypto classes are also extremely poor. They miss out important bits of crypto functionality like support for the PKCS suite of specifications. Pluggable crypto is also desirable for users of hardware with HW acceleration. For example, VIA’s processors can do extremely high performance crypto, because they have dedicated hardware; to use the hardware requires special opcodes and so on. It would be very nice to have an “accelerated” crypto engine in .NET that could do so. Only you can’t, because the entire system isn’t really pluggable, and doesn’t allow seamless drop-in replacements.
“4) In the end, how far off the mapping can you? If the underlying concepts are sound in Win32 (or Microsoft think they are) it’s likely that they’ll think they are for .net.”
But they’re not sound. To take crypto as an example, there’s no reason that the .NET crypto classes should be unable to use PKCS key stores. The reason they can’t is because *the underlying Win32 API can’t*. Windows’ CryptoAPI can’t do this, and because MS has essentially just wrapped CryptoAPI (rather than writing something new from the ground up as is the case in Java), .NET can’t do it either.
And no-one could ever pretend that Win32 UI programming was even close to sound, and yet WinForms exposes it in all its “glory”. You can’t safely write WinForms code without understanding how Win32 UI development works (i.e. about message loops and thread affinity and interactions with COM and so on and so forth), and that’s really, really bad. Win32 was terrible, and “the new shiny” that is .NET should not inflict Win32 on developers.
“5) Cleaner, simpler APIs is nice. Given the choice between my legacy code working or having to change it, I’ll choose working and spend the money elsewhere.”
The bad APIs cost money too. And you seem to be under the belief that changing the API means breaking old code. It doesn’t. .NET has a fairly good versioning mechanism; you could just run the old code against the old libraries. Unfortunately, MS developed the versioning mechanism and then hasn’t bothered to use it.
“6) “… until you want to (say) profile your application, or design a UI, at which point Apple’s tools beat Microsoft’s hands down.”. Maybe. Can I take a class that I’m using for a desktop app in objective-c and use it in a built and tested web framework which includes state, session and postback management?”
Sure. Of course. Nothing special about .NET in that regard.
“Can I add reference to a web service in with the simplicity of vs.net? I’ll trade all of that for a UI designer (what’s wrong with the one in vs.net?)”
The one in VS.NET can’t even produce native-looking UIs.
“7) “None of which works the same as the Office 2007 one.”. As I didn’t name where the code was, I’ll call bullshit on this comment.”
You don’t have to name names. Unless it is the Office 2007 code, it is spectacularly unlikely to work like Office 2007. And since the Office 2007 code isn’t available for .NET programmers, they don’t work the same.
” “Actually, Paint.NET is (arguably) almost entirely GDI+, which is written in C and C++, and which has managed code wrappers.”. Funny. I downloaded the source code. It’s almost entirely C#.”
You need to check again. It does almost all of the heavy lifting using GDI+. Anything in System.Drawing.*, for example, is GDI+.
9) OK. I was a little oversimplistic. But if you’re working in the vast majority of the software industry, data processing, you don’t need to do those things either.
2) What about the LinkedList generic class?
6) A built and tested web framework? Xcode comes with something like asp.net supported by Apple? Show me.
7) So, there’s no way that someone could implement code that works like someone elses?
If Paint.net uses classes written in C++ that are wrapped by C#, who cares? Does it do the job? My point was to demonstrate that you can write code in C# that does things that might be considered as requiring performance. How Microsoft implement their classes doesn’t worry me too much as long as it works.
“2) What about the LinkedList generic class?”
What about it?
I know it exists. My complaint is that I can’t program against it in an effective way using only interfaces. Because of the flaws with the interfaces used in .NET, I have to program against the concrete type.
This isn’t true in Java, and it isn’t true in C++. In both of those languages I can write generic code that works against linked lists and array lists, and is efficient for both. That is because those languages offer me abstractions (ListIterator in Java, the sequence concept in C++) that enable me to develop code that works for both containers.
The same is not true for .NET.
I mean, did you ever consider why Java does not have a public linked list node class, why C++ does not have a public linked list node class, but .NET does? It’s not because .NET provides greater capabilities than Java or C++. It’s because .NET has poorer abstractions than Java and C++, so it has to expose implementation details like nodes in order to provide a reasonable set of capabilities. Exposing linked list nodes is not desirable and it is not necessary, but .NET does it, because .NET has no suitable abstractions to leverage.
“6) A built and tested web framework? Xcode comes with something like asp.net supported by Apple? Show me.”
No, but that’s not what you asked for. I was thinking of something such as SOPE (http://sope.opengroupware.org/). (As a point of fact, Xcode *does* come with its own web framework, but that uses Java rather than Obj-C).
“7) So, there’s no way that someone could implement code that works like someone elses?”
Given that no-one outside MS knows how the Office 2007 ribbon works, no, there’s no way.
“If Paint.net uses classes written in C++ that are wrapped by C#, who cares? Does it do the job? My point was to demonstrate that you can write code in C# that does things that might be considered as requiring performance. How Microsoft implement their classes doesn’t worry me too much as long as it works.”
Good grief.
Paint.NET was being held up as an example of how .NET is “fast enough” (I’m not quite sure why you started talking about performance–the article doesn’t–but you seemed to think it was a problem that needed addressing).
If Paint.NET uses native GDI+ code to do all the heavy lifting, that is not a demonstration that *.NET* is “fast enough”. It’s a demonstration that native GDI+ code is “fast enough”.
Again: the original article never suggested anything about the performance of .NET. But if you are going to hold up an application as a demonstration that .NET’s performance is “fast enough” for application development, an application that does all its heavy lifting outside of .NET is probably not the best choice you could have made.
6) What’s the name of that java web framework that it comes with? I’m curious…
7) But people have used the ribbon, can see what it does and presumably can see how it’s used under win32 to understand the requirements of it? Why can’t someone then work out how to mimic it?
As for paint.net, I suggest you look at the code. Whilst the graphical processes are using GDI, they’re also doing plenty of code that’s within C# doing the maths to, for instance produce clouds.
OK, forget performance. Is .net a useful application that works well and is used by a large number of users?
“6) What’s the name of that java web framework that it comes with? I’m curious…”
WebObjects; it’s a port of the old NeXT-era Obj-C web framework to Java.
“7) But people have used the ribbon, can see what it does and presumably can see how it’s used under win32 to understand the requirements of it? Why can’t someone then work out how to mimic it?”
It is highly unlikely that the mimics would be accurate. They very rarely are.
“OK, forget performance. Is .net a useful application that works well and is used by a large number of users?”
It seems OK for web apps, as ASP.NET is reasonable enough. It is not a good environment for building desktop apps. That is not to say it cannot be done–but rather it falls so far short of what it could have been for such apps.
It could have been much better for web apps too, but I suspect it’s not quite as egregiously horrible for them, because it’s not so tainted by Win32.