Now that we’ve looked at a bunch of myths about when finalizers are required to run, let’s consider when they are required to not run:
Myth: Keeping a reference to an object in a variable prevents the finalizer from running while the variable is alive; a local variable is always alive at least until control leaves the block in which the local was declared.
Finalizers are interesting and dangerous because they are an environment in which everything you know is wrong. I’ve written a lot about the perils of C# finalizers / destructors (either name is fine) over the years, but it’s scattered in little bits over the internet. In this series I’m going to try to get everything in one place; here are a bunch of things that many people believe about finalizers, all of which are wrong.
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?
You’ll have to wait until Monday for the thrilling conclusion to my Wizards and Warriors series. Today on fun-for-Friday FAIC, some thoughts on sawhorses.
I made these light-duty sawhorses out of some scrap two-by-fours in 1997: (Click for a larger image.)
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?
In this series we’re exploring the problem “a player can use a weapon, a wizard is a kind of player, a staff is a kind of weapon, but a wizard can only use a staff”. The best solution we’ve come up with so far is to throw a conversion violation at runtime if the developer makes a mistake, which seems less than optimal.