In object oriented programming, an interceptor is basically a wrapper that tacks additional functionality onto an existing object. If you look it up on Wikipedia, they give what is probably a "better" but more confusing definition. Feel free to peruse.

If you're like me, you were introduced to interceptors in some gigantic framework library thing, and you had no idea what they were for, but you eventually wrote one yourself without knowing it. Later, when you realized what you had done, you wondered why anyone would want to use Castle.Windsor to accomplish the same thing. This article isn't about that. This article is about what happens when you screw up.

That's right, ladies and gentlemen, this is a real defect, discovered in testing, and I wrote it. Names have been changed to protect the innocent (and the guilty). For today, my name is Mud. :)

Take this class, for example:

interface IThing
{
    int GetValue();
}

class ThingImpl : IThing
{
    public int GetValue()
    {
        return 1;
    }
}

Now, let's say you have some other random functionality you want to tack on top of that. For this minimal reproduction, let's say we just want to log that a call to GetValue() was made. This is super easy to do. We already have an interface, after all, because—well, come on. This is a dotnet shop; we use interfaces for everything.

class ThingInterceptor : IThing
{
    private readonly ThingImpl _thing = new ThingImpl();

    public int GetValue()
    {
        Console.WriteLine("Hello!");
        return ((IThing)_thing).GetValue();
    }
}

Fun fact: what I actually wrote here was the following:

class ThingInterceptor : IThing
{
    private readonly ThingImpl _thing = new ThingImpl();
}

I then asked the dotnet compiler to implement IThing for me in terms of _thing, and I added the logging call after the fact. Like I said, it's super easy, barely an inconvenience. Now, what do you do when the original class adds a dozen new methods and you actually don't need to intercept most of them? What if you don't know about that implement-in-terms-of trick that I just told you about—you know, like me, from an hour ago? (Hint: use the light bulb.)

Well, in that case, you might come up with a solution like the following:

class ThingInterceptor : ThingImpl
{
    private readonly ThingImpl _thing = new ThingImpl();

    public new int GetValue()
    {
        Console.WriteLine("Hello!");
        return ((IThing)_thing).GetValue();
    }
}

Warning: THIS DOES NOT WORK.

Ok, but why the hell not?

Because this is a dotnet shop, and we use interfaces for every-damn-thing.

static void Main(string[] args)
{
    IThing foo = new ThingInterceptor();
    ThingInterceptor bar = new ThingInterceptor();
    Console.WriteLine(foo.GetValue());
    Console.WriteLine(bar.GetValue());
}

Since I'm asking the question, you know the answer already, but what do you expect the output of the above program to look like? That's correct, it looks like ass.

1
Hello!
1

Two calls to the interceptor produce only one line reading "Hello!" in Console.Out. This is because we've actually only made one call to the interceptor. The other call was routed, via the interface, to the thing that actually implements the interface, which is not the interceptor.

Two wrongs don't make a right, but in modern, object oriented languages, two seemingly reasonable decisions can certainly make everything go wrong if you don't watch out.

Addendum:

You can actually get around this problem by using override instead of new, because override causes your modified method to replace the original. Basically. There was some reason, in the original code, that I didn't do that. If I had, it would have worked fine. But then I wouldn't have gotten to write this fun article! So...

I guess next time use override.