Community blog feed

Evil code of the day

Website
Blog
Jon Skeet's Coding Blog
Posted
03 Jul 2009 at 22:28

Summary

At a glance, this code doesn't look particularly evil. What does it do though? Compile it with the C# 4.0b1 compiler and run it... using System; class Base {     public virtual void Foo(int x, int y)     {         Console.WriteLine("Base: x={0}, y={1}", x, y);     } } class Derived : Base {     public override void Foo(int y, int x)     {         Console.WriteLine("Derived: x={0}, y={1}", x, y);

Post extract

At a glance, this code doesn't look particularly evil. What does it do though? Compile it with the C# 4.0b1 compiler and run it...

using System;

class Base
{
    public virtual void Foo(int x, int y)
    {
        Console.WriteLine("Base: x={0}, y={1}", x, y);
    }
}

class Derived : Base
{
    public override void Foo(int y, int x)
    {
        Console.WriteLine("Derived: x={0}, y={1}", x, y);
    }
}


class PureEvil
{
    static void Main()
    {
        Derived d = new Derived();
        Base b = d;
        
        b.Foo(x: 10, y: 20);
        d.Foo(x: 10, y: 20);
    }
}

The results are:

Derived: x=20, y=10
Derived: x=10, y=20

I'm very nearly tempted to leave it there and just see what the reactions are like, but I'll at least give you a hint as to where to look - section 21.3 of the C# 4 spec explains why this gives odd results. It does make perfect sense, but it's hideously evil.

I feel dirty.

Bonus questions

  • What happens if you rename the parameters in Derived.Foo to yy and xx?
  • (As suggested by Mehrdad) What happens if you call it with a dynamic value?

Want to stay in touch with what's going on? Follow us on twitter!