I got an email from a customer today, in which he noted that the C# compiler allows
you to write:
bool b = ...
despite the fact that the spec does not list bool as one of the types
that you can switch on.
Unfortunately, we've shipped the current behavior, and one of our high-order goals
is not to break existing code by changing the compiler. In most cases, that's a really
good goal, as your customers are justifiably upset when the new compiler breaks their
In this case, however, I think we may be going to far in not fixing a bug because
there's a chance somebody might have written code that used it. I'm therefore looking
for your opinion (noting, for the record, that it seems that I could sometimes be
replaced by an auto-blogger question-asking piece of software) on what makes the most
How would you have us trade off language conformance (and perhaps language innovation)
vs language stability?
More specifically, when is it acceptable for the compiler to give an error on code
that used to work?
C++ has deterministic finalization. When you declare a stack-based object, at the
end of the scope, the destructor is called before other work is done.
I just finished writing a response on this topic for a customer, and thought I'd share
my favorite reference on the subject with you:
Comcast is planning
on raising its maximum download speed to 3Mbps.
Hope it happens in my neck of the woods...
I've had a couple of questions recently about how to architecture libraries with respect
to exception handling, specifically related to exception granualarity. Questions like:
The first place to start is the Error
Raising and Handling Guidelines from the Design
Guidelines for Class Libraries. There is lots of useful information in the design
guidelines even if you aren't writing libraries. The guidelines do mention something
like "don't use return codes", but that's about it.
One of the high-value design points when designing exceptions is robustness. The robustness
of the customer's code depends directly on the way you structure your exception hierarchy.
Here's some code that I've seen. Assume that ApplicationException is the actual type
I'm catching, not the base type of a hierarchy:
// code here...
catch (ApplicationException e)
if (e.Message.IndexOf("Database Connection Error"))
// recovery code here
There are at least two problems with the code, one major, and one a bit more subtle.
Do you see them?
I'll start with the more subtle one first. If your exception messages are localized,
it's likely that the string matching will fail. This is a bad bug, because it only
shows up in the localized version in an error case, and your tests aren't very
likely to catch it.
The second bug is a whopper. If the exception that comes in isn't a
database connection error, it is swallowed by the catch block, never to be heard
from again. That's pretty much the worst thing that exception handling code
The problem is that the exception design has forced the user to look inside the
exception to decide what to do. This is bad, whether it be the message text,
a return code, or the type of an inner exception that the user is looking for.
To prevent this, I'd recommend the following guideline:
One way to determine this is to ask yourself, "Self, would a user ever care about
the different cases where ApplicationException is thrown?" In some cases this
is obvious, but in other cases, it's not quite so clear. My recommendation is
that you err on the side of more granularity rather than less granularity.
Apparently, I'm "on the Cluetrain",
though strangely, I don't recall boarding, or even buying a ticket.
There are some interesting points here, and I do think that VS has focused mostly
on the "edit and build" side of software development, without taking a larger view.
Will that change in Whidbey? I think you'll have to wait and see.
On Tuesday, I asked a question about whether people keep their form class names and
form filenames in sync. I'd like to thank all who responded, and provide a little
background on the issue. To do that, I'll have to explain a bit about our internal
development a process.
Many of you have probably encountered the problem of "feature creep", where new features
keep showing up during development. Feature creep is bad because it throws of your
completion estimates, makes it hard for your test team to know what you're planning
on building, and generally annoys people. It's especially bad when you have a lot
of interdependent teams, and the new feature isn't something you want but rather something
somebody else wants, and it gets worse if there are multiple teams depending on you.
One way to deal with this is to say, "No new features", after you reach a certain
point in your release cycle. That would work great if planning was perfect, but it's
fairly common to find out that a planned architecture has technical problems, or a
new customer need comes to light, or somebody has a great idea, or a usability study
shows that your current approach flat-out sucks. Not to mention the "we didn't think
of that" factor, which we try to minimize but cannot eliminate.
Our approach is to provide a standard process known as a DCR (Development Change Request).
In a DCR, the PM who owns the feature gets to produce a document that describes:
This usually involves a considerable amount of research by the team, as it's really
important to understand the subject deeply, and the research often involves more than
Once the DCR is written up, the PM (and usually other involved parties) meet with
the management team of their product (in our case, it's our PUM, our dev manager,
our qa manager, and our group program manager) to present the DCR. The management
team will either approve the DCR, reject the DCR, or ask for more data.
In this specific situation, the problem that we're trying to address has to do with
the build system. If you've looked at the PDC
session abstracts, you may have come across mention of something called MSBuild.
MSBuild is a new build system that isn't coupled to the VS project system, which means
you'll be able to build your Whidbey projects from the command line without loading
If you've gone spelunking in your windows forms files, you may have come across a
line that says:
System.Resources.ResourceManager resources = new System.Resources.ResourceManager
Behind the scenes, the Windows Forms designer has put some form resources in a .RESX
file. These resources will get converted to a binary format by resgen.exe, and then
put into the assembly as part of compilation. Since there may be multiple forms in
one assembly, there needs to be a way to find the right resources for a form. For
Windows Forms, the full name of the class was chosen as a key. The project system
finds this out by talking to the Code Model, a sort of "mini in-process compiler"
that also parses code for intellisense and other IDE features (if you read the
PDC session abstracts closely, you'll find a new feature...). The code model tells
the project system what the name of the form is, and this is passed to the compiler
and used to name the binary resource blob in the assembly.
The resource manager constructor gets that same name from the type passed into the
constructor, uses it to find the correct blob, and things are hunky and hopefully,
dory as well.
Enter MSBuild. It seems like a good idea to be able to build windows forms projects
in MSBuild, but there is a problem.
There is no code model for MSBuild to ask for the form name, and no facility to find
that information, so it's DCR time. We've spend the last few weeks talking about different
options to solve this, but none of them are great, and we don't have a single candidate
that we all like.
One of the front runners has the bad characteristic of requiring a project file checkout
whenever the form class name is changed, which could be a problem if the project file
is already checked out exclusively.
If our users typically rename the form file when they change the class name, then
the issue is largely moot, as that rename would also require a project file checkout,
and that's why I asked for your feedback.
Several of the comments talked about the poor state of rename in VS (ie, you can't
do a VSS rename from inside VS). I talked with the VSS PM, and he said that they are
planning to do rename for Whidbey. Please read that as, "It's likely to show up, but
don't get mad at Eric if it doesn't, as it's not his call". I did convey the feedback
I got about the quality of the current solution.
I'm working on resolving an issue, and the way that we decide depends upon the prevalence
of a specific scenario. I'd like to know your opinion on the following Windows Forms
How often do you rename the form class without renaming the file that holds the form
class? ie how often do you change "class EmployeeForm" to "class AddressForm" without
also renaming the form file?
With PDC coming up, there have been lots
of Microsoft entries about what makes a good presentation, and I'd like to throw
my 35 cents into the discussion. Here are three things I like to keep in mind.
Why is always more important than what
Technical people are smart and used to figuring out things on their own. They can
figure out the C# property syntax in their sleep. What they can't figure out is what
was going on in your mind when you wrote a feature, and knowing that is the most
This is also critical for connecting with your audience. Showing some code and saying,
"have you ever had to write ugly code like this?", and then showing the improvement
will always garner a good response (assuming that the feature is actually useful).
It's your job to provide the connection between the feature and the problem it solves.
What you don't talk about is more important than what you do talk about
Technical topics always have lots of subtle and interesting points that you could
talk about. Understand the difference between what you could talk
about and what the audience needs to know, and stick with the simplest scenario to
start with. I've seen lots of presentations where the speaker throws in "interesting"
asides that merely confuse the attendee.
To put it another way, your job as a speaker is to filter the important information
out of all the possible information. If you don't filter out the irrelevant details,
your attendees won't know whether they should understand that information. That will
1) leave them thinking about your previous aside when you want them thinking about
the topic you're now discussion and 2) make them feel stupid.
Your job is not to display your technical mastery of the subject. I don't, for example,
talk about the advanced events syntax when I talk about C# events. It's not relevant
Get concrete fast
Real world examples always beat abstract ones. Don't spend time on introductions when
you could explain it as part of a real-world example, or show as part of a demo
Iterate and embellish
Most topics have several layers to them, either layers of complexity or ordered layers
of discussion. In properties, for example, I would first show the world without properties,
discuss the problems, and then show the world with properties. A building-block approach
is easier for people to understand, and it builds the progression into the presentation
so you can't forget it.
I once came across a presentation guide that suggested not using revelation in presentations
(revelation is when points are gradually revealed). If you're going to present effectively,
you need to be able to focus the discussion on a specific point, and you do this through
revelation. If you have three main points on a slide, and you show them all at once,
your audience will be reading the second and third points while you're talking about
the first. You want them listening to you instead.
Revelation combined with diagrams can be a tremendous learning aid. A good diagram
is worth at least 2^10 words. Consider whether you can express points graphically.
Finally, I have a personal reason for liking revelation. One of the reason I
emjoy presentating is the comedic potential, and an essential element of humor
is timing. The funny part of the slide usually isn't the first part, and
if you don't use revelation, everybody gets to it at different points - if they
notice it at all. You want the impact to hit them all at once, and that's why you
You should also read Conference
Presentation Judo by Mark-Jason Dominus. If you presented before,
this is a phenomenally useful presentation. Make sure you read the notes along
with the slides.
And if you're a Microsoft person who wants somebody to comment on your slides, I might
You drive into work in the morning, and as you drive around the garage, you see some
green objects blocking a stall at the other end of a row of cars. Your first thought
is, "Cool! Health!"
(They were egg crates, but the color match was pretty close)
I needed a splash screen for my music player app. I tried a couple of ideas that didn't
work very well, but then I hit on the idea of using the image
of a CD as the background of the splash screen - and doing a non-rectangular window.
I'll start with the splash screen...
Conceptually, a splash screen is pretty simple - it's just a form that you bring up
at the start of the program. The code is something like this:
splashForm = new SplashForm();
and we'll hook the Activated event to hide the form.
When we run this, however, something strange happens. The form comes up, but it never
renders - there's just a black background. This is because we need the windows messages
to be processed to get the form to paint. There are several ways to do this, but my
choice is to simply call Application.DoEvents() after the form is shown. This processes
any messages that have yet to be processed, showing the form.
Next, we need to make a non-rectangular form. This is done by setting the region on
the form. This is surprisingly easy to do. Here's the code I used for the CD:
GraphicsPath p = new GraphicsPath();
p.AddEllipse(2, 4, 340, 341);
p.AddEllipse(150, 153, 43, 43);
this.Region = new Region(p);
The first ellipse defines the outside of the picture, and then the second one this
inside. This gives me a round window with a hole in the center.
I have a couple of recommendations to make, from my experience buying a used BMW 328i
The first is for my broker, Darrel Kempf. Darrel
ended up owning a very small car lot (4 cars) when he bought some property a number
of years ago, and that somehow turned into a business selling, renting, and brokering
Darrel was recommended to us by a friend that bought a 530 though him. For a flat
rate ($600 in my case, IIRC), he will find a used car for you and transport it back
to his lot, where you pick it up. In my case, he ended up travelling to a BMW auction
in California and then talking to me about the cars that were available on his cell
phone as he walked through the car lot. Overall, a very pleasurable experience, and
I figure we saved at least $4000 on the car over what it would have cost in Bellevue.
He deals in all makes and models of cars.
My second recommendation is for Carfax. After
Darrel had bought the car and before I paid for it, I ordered a Carfax vehicle history
report for $19.99. It told me that there had been no severe accidents reported, that
the odomenter was likely correct, and that it had only had one owner. It also gives
the history of when it entered the US, when it was licensed and emission tested, etc.
Easily worth the money for the peace of mind.
Thanks for all your comments. On the basis of those comments, we've decided not to
change the current behavior. There are two things I'd like to bring out.
First, thanks to Jacob for mentioning that you can set the default behavior. One of
the problems we have with VS is that there is lots of functionality that people don't
know about. I've added this to my "Things that people don't know about list". So,
if you want to change the default, right click and choose "open with". This works
for both Windows forms and ASP projects.
The second concerns options. There were several comments that say, "make it an option,
so people can choose", and then Monte Hansen said, "I think there needs to be a gatekeeper
for project-level options and if it were me, this one wouldn't make it".
I agree with that sentiment. In some cases, you have to provide flexibility - for
example, if you had a feature that said "braces must go on the line after the if statement",
you would make lots of people unhappy. That would be a Bad
But there are other cases where adding an option is is the simple way out - either
because a team can't agree on what should or shouldn't be there, or because the team
hasn't worked hard enough on what the customer wants (these may really be the same
thing - not knowing your customers well enough). It's easy to say "let's make it an
option", but in a product like Visual Studio, there are already too many opaque options.
There may be some interesting ways of fixing this - like making the options that pertain
to a window actually be accessible from that window - but in the category of options,
fewer is already better.
I was looking through the options in VS2003 for one where I could say, "Does anybody
ever set this option". I had just read Mark's comment:
One feature that disappeared between 2002 and 2003 that really drives me nuts,
was that when you changed between document tabs the project tree view would update
to select the current page you are viewing
and what do I find? Under "Projects and Solutions", there's an option named "Track
active item in solution explorer" that I think does what Mark wants. We didn't take
the feature away, but we did do a good enough job of hiding it that it appeared that
it was missing. That's a good indication of why "make it an option" can be a bad choice
- we put effort both into coding something, making it an option, and then testing
it, but we hide it so that our users get little benefit from it. Many times the effort
to do this just isn't worth the return, as an unfound option is no different than
a feature that doesn't exist.
We had a similar situation back when I was on the C++ compiler team. User asked
us for more information to help them find problems in their code, and there were a
number of situations that the compiler could identify. Unfortunately, in many cases,
the compiler would warn on perfectly reasonable code, and since many people compile
with "warn as error" on, we couldn't make them level 2 warnings, as it would break
lots of existing code.
So we made them level 4 warnings, but the result was that since the default was level
2, almost nobody got any benefit out of the work that we did, so we stopped adding
Thanks again for your comments
I've been home sick today, so I didn't get to post this until now.
Today is "Talk like a Pirate" day
Today, I accidentally figured out that the "off" button on my XBox isn't just an off
button. It's also an on button, and it's one that doesn't eject the disc first, so
you don't have to wait for the tray to come out and push it back in.
I've been cleaning my office today, and I need some help on a problem I have.
Back when I wrote my C# book (A Programmer's Introduction to C# (still available at
better booksellers everywhere (Eric needs to pay for his season's pass at Stevens
Pass (where it snowed this week (view the webcam))))),
I was lucky enough to have the first edition translated into a number of different
languages. Whenever a publisher would finish a translation, my publisher (Apress,
new owner of most of the Wrox titles) would send me a box of books. I always put one
on the bookshelf, and when I had one that I thought somebody would be interested in,
I'd give it to them. For example, I gave my Czech mother-in-law a copy of Začínáme
programovat v C# , and Anders got a copy of
But after a while, I exhausted the humorous potential of giving relatives copies of
books that not only covered topics they didn't understand, but were written in languages
they didn't speak, and I'm left with a number of copies that I don't know what to
do with. Most are the first edition of the book, which is nowhere near as good as
the second edition.
So I'm looking for ideas of what to do. I currently have:
2 Korean (2nd edition)
I have a design question for you. Yes, I don't own the project system anymore, but
I started this particular issue, and I want to follow up on it:
In VS 2002, whenever you double-click on a form file in solution explorer, the project
system always opens the form designer on that file.
We are considering modifying the behavior in Whidbey so that the project system will
track the most-recently-viewed state for the file. If you had most recently looked
at the code view, double-clicking would take you to the code view. If you had most
recently looked at the design view, double-clicking would take you to the design view.
This state would not be persisted across closing and reopening the project.
What do you think? Should we stick with the current behavior, or should we change
to the new behavior? And why?
The C# team has finally decided who is going to PDC, and I'm going to California,
though I am not going to make a new start, nor do I current have an "achin'" in my
(1) Too lazy to do a google search, huh? Too young to know better. Okay, just this
(The opinions expressed herein reflect my opinion about the principles we used in
designing C#, and do not necessarily reflect the opinions of the C# design team).
Know what you're trying to build
Over the past few years, I've answered a lot of questions about language design rationale.
Most questions have straightforward answers. For example, if somebody asks "Why doesn't
C# have macros?", that's easy to answer.
Other questions require a bit more work, and/or may be religious discussions. "Why
are methods non-virtual by default?" takes more time to answer.
The toughest ones to answer aren't tough because they're technically hard - they're
tough because it's hard to give a nice answer to. This is usually because doing what
the person requests would require changing one of the basic tenets of the language.
Our goal in C# was to create a modern, real-world managed language that would be comfortable
to developers used to the C family of languages (C, C++, Java, etc.). So, when I get
questions like, "Why is C# case-sensitive?", they're really hard to answer. The real
answer is that our target users would think we were crazy if we made a language that
wasn't case-sensitive. You can say this in a polite way, but the person who asked
the question is usually confused by your response. Their perspective is often "of
course a language should be case-insensitive", which is diametricly opposed to the
Similarly, I've been asked why C# doesn't allow you to define your own operators.
There are some languages that allow you to do that, but that's very much not what
Re-reading this, I'm not sure it's terribly insightful, so I'll try to summarize.
When you're designing a language, you need to be clear up front what you're trying
to build, and who is going to want to use that. Those early decisions are going to
have a huge impact on the design of the language, and once you've made them, you can't
really go back.
Last week, I made a bad joke (I'm the owner of bad jokes for the Visual C# PM team),
related to the the concept of arity in generics. I regret that I don't remember the
exact joke I made, but we riffed a bit on different permutations (popul-arity, singul-arity,
disp-arity). That went on for a few minutes, but we realized that it ws a tough joke
Then Julian (one of our IDE PMs) suggested that we could communicate it better through
code. Here's what he suggested:
Once you've done this, then people can discuss the Hil-arity and Jocul-arity of
You may have noticed that we often don't aspire to particularly high standards of
If you ever want to find words that contain a certain string of letters, I suggest OneLook.
Roy Osherove writes of some very
interesting research in his blog.
I've always found research about how we read to be fascinating
column is live on MSDN. This one shows the socket-based peer-to-peer system that
I built for my ongoing music scheduling project. As you may or may not know, there
is no support for serialization on the compact framework, so I had to build my own.
It ended being pretty cool.
In other news, last week one of my previous column made the from page on microsoft.com.
First time for that.
Over the past few years, we've gotten lots of suggestions and questions about the
C# language, and we haven't done a very good job responding to them, for a variety
The first reason is that we haven't devoted as much time as we probably should have
to interacting with customers on the subject of language design. That's something
I'll be trying to improve in the next few months. You can expect to see some more
information about new language features before we give out bits at PDC.
The second is a bit harder to explain. Basically, it revolves around whether a feature
fits into what I'll call, for want of a better term, "The C# Philosophy". Some of
the philosophy can be reduced to guidelines or rules, such as "Simplicity is also
a feature", but there remains a fair portion that is really just based on the informed
judgement of those on the design team. On some issues, that can make it
really hard to communicate why we made a specific decision, as it's hard to put into
words how we make our choices.. In the words of one of the design team members,
"it took me 6 months of design meetings before I stopped making a fool of myself".
For me, I think it was close to a year.
So I don't expect the communication to be perfect. But it should be a lot better.
I'm hoping to devote a number of entries to some of the guidelines we use. Note that
this is really on my view of the philosophy of the design team, so don't view this
as the definitive view. Guidelines I hope to cover:
I'll try to do one of these each week.