Click here to Skip to main content
Click here to Skip to main content
Go to top

Not Another C# Versus VB Article

, 20 May 2005
Rate this:
Please Sign up or sign in to vote.
It's not about feature support. It's about culture.

Contents

Introduction

This article explains the benefits of a Microsoft .NET application development organization coding in C# versus coding in VB.

It's common knowledge that VB.NET and C# are functionally equivalent. Hence a frequently-heard argument for choosing one or another is that because they are functionally equivalent, neither poses a clear advantage. This argument has merit, but because it attempts to be diplomatic and avoids subjective opinion, it fails to get to the heart of the matter.

This article does not simply consider objective arguments. Rather, I attempt to explore some of the highly subjective factors which influence developers working in VB versus C#. These subjective factors taken collectively over time contribute to a certain culture. The VB culture is different from the C# culture.

By examining the history of the two cultures and their current trends, we can make predictions about how the choice of one language or another might influence the production of quality code in a production shop.

The culture of Visual Basic

The purpose of Visual Basic was to create a mass market for software development tools. Prior to Visual Basic, application development languages were viewed as complex and restricted to the domain of skilled programmers. Visual Basic was syntactically simple, and it enabled virtually anyone with a few hours of time to learn how to create simple applications. In the days when software development was seen as more of a black art than an engineering discipline, the ability to be able to join the ranks of “software developers” was a powerful aphrodisiac for many computer users.

And join they did. Millions of “power users” of computers became millions of “software developers”. It happened that Visual Basic came along just as the demand for new software applications was escalating rapidly, driving demand and hence higher salaries for software developers.

The fact that Visual Basic was lacking in the fundamental building blocks of object oriented programming didn’t matter much at the time. Software was still relatively simple. Distributed application development was client-server at best. The web was so new that application development models for it had barely started to evolve—the business world didn’t even know where the web was going, so how could developers possibly know how to program for it? Web applications were hacked together, and it didn’t matter. To compound the hacking methodology, the sheer demand for web applications began to accelerate at a pace that exceeded even the wildest expectations by an order of magnitude. Application developer salaries skyrocketed, demand continued to increase, and the perceived need for a sane, sustainable application development model was left trailing far behind.

The peak of this trend coincided with the peak of the Internet boom. Vast armies of grossly under skilled developers were paid enormous sums of money and elevated to cult-like status to hack together anything that would even remotely resemble a software application. And Visual Basic, with its lack of formality and constraints that might slow down the hacking process, was just the right food for the frenzy.

Visual Basic was launched in March of 1991. In 2000 Microsoft announced .NET. in a move that swept the slate clean and replaced Visual Basic with what was in effect an entirely new development paradigm. The underlying classes against which programmers developed were completely replaced by the .NET Framework. The kludgy third party tools were swept aside and replaced by a clean third party tool model. The lack of inheritance and the limited implementation of polymorphism enforced for so many years by the underlying limitations of the Visual Basic engine architecture was overcome by throwing the old engine out completely.

With these changes, Visual Basic was reborn as a powerful new development platform, functionally equivalent to C#, J# and Java. In fact, of the Visual Basic of the 90’s, only two things remain today; the culture and the syntax. The culture of Visual Basic is the culture of the 90’s: build it fast, hype it up, sell it, and don’t worry about whether the story will hold together tomorrow, or even hold together at all.

To grasp how this culture affected trends in software development, it’s instructive to hear what Niklaus Wirth had to say about it in 1997. Niklaus Wirth is one of the most influential thinkers in the software world. A professor at ETH Institute in Zurich, Wirth designed Pascal, Modula 2 and Oberon. In the early 1970s, he was one of the people who proposed program development by stepwise refinement. He's the author of many important books, including "Algorithms + Data Structures = Programs" (Prentice Hall, 1975) and "Systematic Programming" (Prentice Hall, 1973) He was awarded the Turing Prize in 1984, and has also received five honorary doctorates and several other awards.

In a well known interview with Dr. Carlo Pescio, published in Software Development, June 1997, Pescio asks Wirth:

You probably know about the 'good enough software' concept popularized by Yourdon. In many senses, it's just a rationalization of what's happening in the software world: the first company hitting the market with a feature-rich product is more likely to win the battle than the careful, quality-seeking company. Do you think there is anything developers and software organizations can do about that? I guess many developers would be happy to be given more time to develop better software, but at the same time they are rushed in the name of corporate survival. 'Educating the users' seems more a wild dream than a possibility.

to which Wirth replies:

'Good enough software' is rarely good enough. It is a sad manifestation of the spirit of modern times, in which an individual's pride in his/her work has become rare. The idea that one might derive satisfaction from his or her successful work, because that work is ingenious, beautiful, or just pleasing, has become ridiculed. Nothing but economic success and monetary reward is acceptable. Hence our occupations have become mere jobs. But quality of work can be expected only through personal satisfaction, dedication and enjoyment. In our profession, precision and perfection are not a dispensable luxury, but a simple necessity.

Recently I read a final report of a research project funded by the Swiss National Science Foundation. The project's naive goals were identified as follows: First, how can easy programming be achieved (in particular, for non-experts)? Second, how can a mechanism be realized that allows hiding the difficult parts of parallel programming? After more than 30 years of programming we ought to know that the design of complex software is inherently difficult. This despite of the fact that, for decades, the industry has been advertising programmers' positions by claiming that programming is easy. Later on, when doubts arose even to the advertisers, they switched to promising a wide variety of tools to facilitate the arduous tasks. Tools became the slogan; the right tools, paired with clever tricks and serious management methods, would work wonders. Then Edsger Dijkstra called Software Engineering 'Programming in spite of the fact that you can't'.

Indeed, the woes of Software Engineering are not due to lack of tools, or proper management, but largely due to lack of sufficient technical competence. A good designer must rely on experience, on precise, logical thinking, and on pedantic exactness. No magic will do. In the light of all this it is particularly sad that in many informatics curricula, programming in the large is badly neglected. Design has become a non-topic. As a result, software engineering has become the El Dorado for hackers. The more chaotic a program looks, the smaller the danger that someone will take the trouble of inspecting and debunking it."

In a minute, we’ll look at how the culture of Visual Basic affects the quality of code produced, even today, and how the last remaining vestige of Visual Basic, the syntax, unfortunately continues to reinforce the culture.

But first, let’s review the culture of C#.

The culture of C#

To understand the culture of C# is to understand the story of Anders Hejlsberg, its chief architect. Hejlsberg deeply admired Niklaus Wirth. Wirth created the Pascal language from Algol, the first high-level language with a readable, structured and systematically defined syntax. Hejlsberg created the world’s first compiler for Pascal, and extended the language to include object-oriented capabilities (Object Pascal). Both were focused on the language’s elegance, at least in part because the language was designed as a teaching tool for students of programming languages to learn structured, and later object-oriented, development techniques.

Pascal was first embedded in a commercial development environment by Borland, with the release in November 1983 of Turbo Pascal, which employed Hejlsberg’s compiler on a licensing arrangement. Hejlsberg worked for Borland for thirteen years from 1983 to 1996 during which time he was the chief architect of Turbo Pascal and later Delphi.

Delphi, a direct competitor to Visual Basic, was regarded as vastly superior technically, even by Microsoft, who routinely plundered its inventions. To preview some of the features of each successive version of Visual Basic, it was generally recognized that one only had to look at the current version of Delphi.

Delphi, however, was hampered by a relatively insignificant development and advertising budget. While Microsoft plowed hundreds of millions of dollars into promoting Visual Basic, Borland had to rely primarily on technical excellence to drive usage through word of mouth. Hejlsberg knew his work would never achieve mainstream adoption while he remained at Borland. At the same time, Microsoft gradually came to realize that Visual Basic would never achieve the technical excellence of Delphi without Hejlsberg.

About the time when these two forces were starting to draw Hejlsberg and Microsoft together, a thunderbolt hit that would dramatically accelerate the fusion. That thunderbolt was Marc Andreessen’s endorsement of a brand new language (or at least one with a brand new name): Java.

Java’s precursor was developed by Sun’s Patrick Naughton, Mike Sheridan, and James Gosling in 1990-92, who had the far-reaching notion of connecting together small devices, such as video recorders and televisions, in cyberspace with a common programming language. The first version of Java was called “Oak” and was architecture-neutral, distributed, portable, object-oriented and secure. Although these qualities turned out to be just the qualities needed to develop applications for the web, the adoption of Oak for the web would have to wait until 1994. But the fact that Oak’s true potential would take several years to recognize was much less important than the culture in which it was born. For in 1990, Naughton, annoyed with the disparate directions in which Sun was heading, nearly quit and took his work to the more idealistic and focused neXT, owned by Steve Jobs. It was only because Sun’s CEO, Scott McNealy, solicited a report on the failings of Sun from Naughton, and heeded the report, that Naughton stayed. McNealy agreed Naughton would be allowed to create a small team of engineers outside of mainstream Sun in order to “do fewer things better."

Designed by a small team dedicated to technical excellence, Oak/Java was the antithesis of Visual Basic. Yes, it was more difficult to learn, but it was more powerful. And the proof was in the pudding. Java applications, when architected and built by skilled Java developers, were more powerful and feature-rich than the vast majority of Visual Basic applications.

Marc Andreessen, CEO of Netscape and therefore the “God of the Internet” at the time, was one of those who saw the potential of this new language. In 1994 he told the San Jose Mercury News: "What these guys are doing is undeniably, absolutely new. It's great stuff."

Coming from most people, such an endorsement would have been just another spark. Coming from Andreessen, it was the thunderbolt that shocked the world into a near-frenzied adoption of Java, and ultimately brought Microsoft and Hejlsberg together.

For Java was not perfect either, and by then the brilliant Hejlsberg was envisioning the next generation of application development language. Hejlsberg envisioned a language which would fully embrace the emerging component model for application development by making the three key constructs of component development—properties, methods and events—first class elements of the language.

In Java, for instance, properties don’t really exist. They’re “faked” by using the get xxx and set xxx syntax. In a property inspector they show up as “xxx” and you have to know that you put the get and set in the right places. This and other anomalies made Hejlsberg the perfectionist uncomfortable. He felt that the ideal language would require no such kludges or workarounds, but should instead roll all of the core constructs right into the syntax, giving the programmer a “one stop” experience. The problem was that this would require fundamental rewiring of the compiler, and significant research and development expense.

With Java rapidly gaining ground, by 1996 Microsoft was getting very concerned. They were taken off guard by the fact that an elegant, precise language that required a significant degree of programming skill and dedication to use effectively was making headway against Visual Basic. They also recognized that they needed more than just some reworking of the Visual Basic engine. They needed fundamental change. They made Hejlsberg an offer he couldn’t refuse. If he would come to Microsoft, he would be given a clean slate and a massive budget to create a “perfect” version of Java. In 1996 Hejlsberg began work on Microsoft’s J++ 6.0 and WFC, the Windows Foundation Classes for Java, as chief architect of both.

Microsoft J++ 6.0 and the WFC, born out of intense desire by the world’s most qualified software architect to make the very good Java even better, were the successors to Object Pascal and the Delphi Visual Component Library. And soon they would become the precursors to C# and the .NET Framework.

For in 1997, Sun sued Microsoft over the changes it was making to Java, stopping the work cold.

Undeterred, with massive financial reserves, and wanting to get even with Sun, Microsoft upped the ante. It gave Hejlsberg an even cleaner slate, the mandate to write a new language that would be better than Java, and backed by a programming toolkit that would be better than Java’s.

The result, born in a culture that puts technical excellence first, unfettered by prior constraints and guided by the wisdom not only of Hejlsberg’s years of experience with Turbo Pascal and Delphi, but also by the wisdom gleaned from Java, is the C# language.

Syntax, semantics and cultural persistence

We've seen that the cultures of VB and C# are very different. And we've seen that this is no fault of the programmers who use them. Rather this is a product of the combination of factors that collectively could be called their upbringing—business environment, target market, integrity and background of the original language developers, and a myriad other factors.

One factor, however, that seems to have a greater effect on the culture than others, is the syntax and semantics of the language.

To what extent do syntax and semantics play a part in the culture that builds up around a language and to what extent, vice versa, do the syntax and semantics depend on the culture in which the language was created?

The truth is, both—just as spoken languages both grow out of culture and influence culture. For instance, in the far north the language syntax has evolved several words for the different types of snow. Interactions then use the language to express nuances of snow, creating a more snow-centric culture.

So in Visual Basic, the decision to include in the syntax and semantics the ability to assign numbers directly to strings and vice versa was a result of the designers’ desire to attract a broad base of developers who would probably not understand the notions of strongly typed variables. Once the syntax permitted it, such assignment became widespread, reinforcing the designers’ original premise.

Once this cycle of self-reinforcement begins, the cultural habits quickly become entrenched and widespread, and are extremely resistant to change. Minds tend to gravitate to like minds. User groups tend to attract homogenous followings. Visual Basic instructors tend to propagate what their instructors taught them.

This awareness of the immense inertia of embedded culture is precisely the brilliant insight that caused Microsoft to keep Visual Basic and to make it nearly 100% backward compatible at the syntax level. They recognized that trying to get legions of developers to abandon their old cultural norms and adopt new ways was foolhardy.

The brilliant insight Microsoft had was not to support multiple languages—if this was the case then surely it would not have bothered with J#, which is syntactically so close to C# that support for language’s sake alone would be ridiculous. The insight Microsoft had was to support multiple cultures.

In concrete terms

What does this mean in concrete terms? What impact does this have on today’s application development? How does the decision to adopt Visual Basic or C# affect programs written today and tomorrow?

  1. 80% of C# programmers are good, while 80% of VB programmers are not good. This is not to say that everyone who programs in VB is less skilled than everyone who programs in C#. This is to say that:
    1. the VB syntax and semantics is designed to attract less skilled programmers and, in combination with other factors examined above, this has created a culture that is populated with less skilled programmers.
    2. and because VB syntax and semantics make it more difficult to avoid common programming errors and hence to program well.
  2. Hiring a good C# programmer is easier than hiring a good VB programmer. This is because of (1).
  3. Hiring the average C# programmer costs more than hiring the average VB programmer. This is because the average C# programmer is a better programmer than the average VB programmer, and this is because of (1).
  4. Hiring a good VB programmer costs the same as hiring a good C# programmer. There are many good VB programmers, and some of them are much better than some C# programmers. However this is the exception, not the rule.
  5. A good programmer accomplishes two to ten times what an average programmer accomplishes, and causes 90% less bugs and headaches.
  6. At the time of writing there are probably almost as many good VB programmers as there are C# programmers. This is because there are many more VB programmers than C# programmers. The 20% of VB programmers who are good is about same number as the 80% of C# programmers who are good.
  7. In the near future, there will be less good VB programmers than C# programmers. This is because many of the good VB programmers are switching to C#. This is partly because they like the language better, but mostly because they like the culture better. As the cultural separation becomes more evident and self-reinforcing, it will accelerate until there are very few good VB programmers left.
  8. VB programmers, on the average, know less about good object-oriented, distributed, loosely coupled application design and development than C# programmers, on average. This is because their language has not supported these notions, so their culture has grown without them. Although these notions are supported now in VB, they are more slowly being adopted than in the C# culture because of cultural inertia.

Propagation of the culture in .NET

Under .NET, the VB language retains constructs that support the existing (old) VB culture. This was done, of course, in order to avoid alienating the culture’s members. Many of these constructs are still used by VB programmers, even though they should be avoided. Others are not harmful except in as much as they continue to provide cultural reinforcement of habits, including those that are harmful. Examples of key differences are listed below. These are simply examples and not an exhaustive list:

  1. VB by default allows support for late binding. Although it can be turned off with Option strict, the culture is such that it’s usually left on. This leads to numerous difficulty to catch errors. C# binding is always early.
  2. VB still supports the old On error goto construct. This leads to sloppy or non-existent error handling. C# supports only the superior trycatch error handling.
  3. VB supports optional parameters. Although VB developers often list this as an advantage, it is a disadvantage because the use of optional parameters weakens the contract between the caller and the method, allowing the developer to slacken his analysis and get away with it until bugs creep in. [Note: C# param array construct is not the same as optional params]
  4. VB supports the legacy VB functions, with reference to Microsoft.VisualBasic.dll. Many of these functions are slow and they should all be avoided in favor of the .NET Framework. However many VB programmers still use them. In new VB projects, this dangerous namespace is included by default.
  5. VB allows implementation of interfaces with methods of different names, making it confusing and difficult to find the implementation. C# does not.
  6. VB supports background compilation. While this speeds the development cycle for small projects, it slows down the IDE in large projects, contributing at least in part to the culture tending to gravitate toward small projects.
  7. C# namespaces are managed in way that makes programmers aware of namespaces and their importance. VB namespaces are managed in a way that hides them from the programmers by default. Careful attention to namespace management is a fundamental tenet of strong application design and its importance cannot be overestimated.

Conclusions

Conventional arguments between Visual Basic and C# focus on the functionality differences. Since these differences are minimal, it is argued that the choice of VB or C# should remain a matter of personal preference.

These arguments fail to take into account the deep cultural differences between the VB and C# camps.

The truth is that while there are some exceptional VB teams that write exceptional quality code, this is the exception, not the rule. Most VB teams have trouble writing high quality code, and this trait is ingrained deeply into their culture by environmental factors beyond their control, and continues to be propagated by the VB syntax and semantics in Microsoft .NET.

Therefore:

  • If an organization is content to write average quality software and has average VB developers, there may be no benefit in switching to C#.
  • If an organization has an exceptional VB team and wants to continue to improve, there is a real danger in continuing in VB. The danger is that the programmers will leave for opportunities in C#. Once even one top developer does this, the polarization of the group towards the old VB culture may accelerate, thus accelerating the attrition.
  • An organization with an exceptional VB team should switch to C#. The exceptional VB team will have no problem learning the new syntax, so there is no danger. The team will then reap the benefits of the C# syntax, semantics and culture for years to come.

Revision history

  • April 19th, 2005: Minor grammar fixed and removed reference to an internal project in our shop that is meaningless to the broader audience. Clarified several sections that might be taken to be slights against VB developers to indicate that it's not VB developers that are the problem. It's the upbringing of the language in the context of the environment... i.e. its culture. Removed section of additional benefits of C# since it's orthogonal to the point.
  • April 19th, 2005. I apologize to anyone who is or was offended by this article. Please read it carefully. If after reading it carefully you think that it slights good VB developers, please let me know exactly where/how and I'll fix up the article. My intention is not to slight any good developer, or even a bad one who's trying. Criticizing the factors that lead to a culture that makes it difficult for developers to be good... now that I have no problem doing.
  • April 22nd, 2005: I'm getting so many comments about how I say that C# is a better language than VB (even though I never say this) that I edited paragraph 2 to reflect that they are functionally equivalent.
  • May 10th, 2005: DotNetRocks' Carl Franklin read my article and commented on it in a recent issue of DotNetRocks, which you can download here: .NET Rocks! - Kimberly Tripp on SQL Server 2005. Being pro-VB, Carl was pretty negative on the article. I would have no problem with that except that I thought that he also missed the point and tried to ridicule the article by taking excerpts out of context. But you be the judge. I've transcribed his comments word for word in a comment slot below, so you can read them, comment, and, of course, rate his comments.
  • May 20th, 2005: Some posters have asked me to indicate that this article, and in particular the 80/20 comment, are based on my opinion and not on empirical or statistical data. They are my opinion.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Nigel Shaw
President Exia Corp.
Canada Canada
I grew up in a small town outside Montreal, Canada, where I grew to appreciate the Francophone culture, the hospitality of rural Quebec and the awesome skiing of the Eastern Townships. I studied Computer Science at the University of Waterloo, Classical Guitar at the University of Toronto, Electrical Engineering at the University of Ottawa, and earned an MBA at Queen's University.
 
I'm a partner in Exia Corp, developers of The Exia Process for better software project management.

Comments and Discussions

 
GeneralIrrelevant vote 1 Pinmemberalfredolopez123411-Jul-14 5:24 
GeneralEven Bob Tabor is shying away from VB Pinmemberamgt1021-May-13 11:36 
QuestionYou owned me! PinmemberBBGq25-Jun-12 7:00 
AnswerRe: Criticism on the article PinmemberNigel Shaw25-Jun-12 7:25 
GeneralMy vote of 2 PinmemberSentenryu13-Mar-12 1:09 
GeneralMy vote of 5 PinmemberJosema2-Jan-12 3:31 
GeneralMy vote of 5 PinmemberManuel_Perez_II8-Aug-11 17:16 
GeneralMy vote of 5 PinmemberShahin Khorshidnia4-Jul-11 1:14 
GeneralLooking back 6 years later Pinmemberreinux2-May-11 15:21 
GeneralBrave author Pinmembera2modmanager8-Feb-11 11:14 
GeneralMy vote of 5 Pinmemberbillybiro3-Aug-10 22:41 
GeneralRe: My vote of 5 PinmemberJohn Grove1-Nov-10 10:36 
GeneralRe: My vote of 5 [modified] PinmemberMember 51104943-Nov-10 5:29 
GeneralCulture smulture -- a big reason for C# popularity. Pinmemberineedajobsoon3-Aug-10 11:56 
GeneralThis has to be made by some microsoft IT or staff guy. Pinmemberw_or9-Jun-10 8:20 
GeneralMy vote of one on your response PinmemberKeith Barrow24-Jun-10 3:17 
GeneralMy vote of 2 Pinmembercrobor2-Aug-09 17:35 
GeneralA list of (relevant) facts for a switch from VB to C# Pinmembercrobor29-Jul-09 18:07 
GeneralMy vote of 1 Pinmember_Khallaf9-Jul-09 15:47 
GeneralRe: My vote of 1 PinmentorKeith Barrow6-Mar-14 2:28 
GeneralRe: My vote of 1 PinmemberNigel Shaw6-Mar-14 2:42 
GeneralRe: My vote of 1 PinmemberNigel Shaw6-Mar-14 2:44 
GeneralYou C# guys have it all wrong PinmemberAlexander Higgins21-May-09 17:44 
GeneralGreat! PinmemberBBGq25-Jun-12 12:23 
GeneralMy vote of 1 PinmemberNic Rowan12-Mar-09 20:32 
GeneralRe: My vote of 1 Pinmembervijaca17-Apr-09 0:43 
GeneralStatistics are facts, not opinions - you should rewrite PinmemberAlan Lindsay11-Feb-09 21:02 
GeneralAnders Hejlsberg PinmemberMaximilian Mayerl22-Jan-09 5:17 
GeneralMy vote of 1 PinmemberRedmist7719-Dec-08 20:25 
QuestionWho says C# is more terse? Pinmemberlianaent13-Nov-08 5:40 
AnswerRe: Who says C# is more terse? PinmemberLawrence Thurman24-Nov-08 9:10 
GeneralRe: Who says C# is more terse? PinmemberAlan Lindsay11-Feb-09 20:26 
GeneralRe: Who says C# is more terse? PinmemberAlexander Higgins21-May-09 18:10 
GeneralRe: Who says C# is more terse? PinmemberAlexander Higgins21-May-09 19:04 
GeneralC# to copy features from VB.net PinmemberOlivier Giulieri27-Oct-08 19:05 
GeneralRe: C# to copy features from VB.net PinmvpGuffa27-Oct-08 23:28 
GeneralWaste of space PinmemberMember 112179722-Sep-08 8:22 
GeneralTotally agree Pinmembercockiest30-Jul-08 18:06 
GeneralThe truth hurts Pinmemberixup6-Jun-08 4:31 
GeneralRe: The truth hurts Pinmembermcmullets6-Jun-08 6:43 
GeneralRe: The truth hurts Pinmemberyassir hannoun14-Jun-08 4:01 
GeneralA point of view from a BASIC programmer... PinmemberRobert Royall7-Aug-07 7:55 
GeneralRe: A point of view from a BASIC programmer... Pinmembermaxxnostra13-Aug-08 8:16 
GeneralRe: A point of view from a BASIC programmer... Pinmemberjoeller15-Aug-08 3:36 
GeneralThe hidden face of VB PinmemberOlmo del Corral31-Jul-07 15:18 
GeneralRe: The hidden face of VB PinmemberNigel Shaw31-Jul-07 15:35 
GeneralRe: The hidden face of VB PinmemberOlmo del Corral31-Jul-07 15:51 
GeneralAt LAST!!! Pinmembermelchizidech12-Jul-07 2:59 
QuestionNotice that... Pinmemberecsmoore23-Jun-07 0:27 
GeneralThanks from a VB guy Pinmemberecsmoore23-Jun-07 0:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 20 May 2005
Article Copyright 2005 by Nigel Shaw
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid