We’ve been struggling in the last four episodes to encode the rules of our business domain — which, recall, could be wizards and warriors or papers and paycheques or whatever — into the C# type system. The tool we’ve chosen seems to be resisting our attempts, and so maybe it’s a good time to take a step back and ask if we’re on the right track in the first place.
The fundamental idea in the first and second episodes was use the type system to detect and prevent violations of the rules of the business domain at compile time. That effort has largely failed, due to the difficulty of representing a subtype with a restriction, like “a
Wizard is a
Player that cannot use a
Sword. In several of our attempts we ended up throwing exceptions, so that the rule was enforced by the runtime rather than the compiler. What is the nature of this exception?
Last time we saw that in order to decide what code to call based on the runtime type of one argument — single dispatch — we could use virtual dispatch. And we saw that we could use the inaptly-named Visitor Pattern to emulate double dispatch by doing a series of virtual and non-virtual dispatches. This works but it has some drawbacks. It’s heavyweight, the pattern is difficult to understand, and it doesn’t extend easily to true multiple dispatch.
I said last time that C# does not support double dispatch. That was a baldfaced lie! In fact C# supports multiple dispatch; you can dispatch a method call based on the runtime types of arbitrarily many arguments. Here, let’s dispatch based on the runtime types of two arguments:
So let’s digress for a few episodes here. We’ll temporarily leave aside the problem of how we can have both a
Player that has a
Weapon and a
Wizard that has a
Dagger.) Supposing that we can figure out how to get that all represented, here’s another problem. Suppose we’ve also got
Vampire classes that are a kind of
Monster. We want a rule that says that if a
Warrior tries to hit a
Werewolf after midnight then the probability of success is lowered. (
Wizards have no such penalty because… magic? Work with me here.)
Wait a moment — isn’t it always after midnight? When could you safely feed a mogwai, anyway?
This will be my last post before I head off for my annual vacation in Canada; see you again in September for more Fabulous Adventures in Coding!
Last time on FAIC I suggested a rule for translating nested “from” query expressions into a much simpler form than the C# specification requires. Why does the C# specification not use my simplified form?
In fact what I showed yesterday is pretty close to what the LINQ translation rules for
SelectMany queries looked like shortly before shipping C# 3.0. The problem with it becomes apparent when you consider the following: Continue reading
Overload resolution is of course the process of taking a bunch of things with the same name and figuring out which of them the user meant. Different languages use different heuristics to try to figure this out. A “heuristic” is just a fancy word for a guess, and I’ve often said that one of the design characteristics of C# is that it is not a “guess what the user meant” kind of language. So if C# is going to make guesses, at least the process by which it does so should be easily explainable to users. Continue reading
Today on the Coverity Development Testing Blog‘s continuing series Ask The Bug Guys, I take a question from an “Eric L”, who is confused about one of the subtle rules of method type inference despite having written the rule himself. My colleague Jon takes a question from a beginner C programmer about memory allocation.
As always, if you have questions about a bug you’ve found in a C, C++, C# or Java program that you think would make a good episode of ATBG, please send your question along with a small reproducer of the problem to
TheBugGuys@Coverity.com. We cannot promise to answer every question or solve every problem, but we’ll take a selection of the best questions that we can answer and address them on the dev testing blog every couple of weeks.
We have two posts today on the Coverity Development Testing Blog‘s continuing series Ask The Bug Guys. First, my colleague Jon explores a tricky difference between the 1989 and 1999 C standards involving conversions of array types to pointer types that can cause undefined behavior if you’re not careful. Then I discuss why Reflection and constructors (or any other method, for that matter) with default parameters do not play nicely with reflection.
Thanks to readers Dennis and Laurence for these interesting questions. If you have a question about a bug in your C, C++, C# or Java program, please send it to TheBugGuys@coverity.com; we’d love to see it. We can’t guarantee an answer to all your problems, but we will pick a selection of the best questions and post about them on the development testing blog. Past episodes can be found here, and the RSS feed for the blog is here.