Beware : Some times “Named Parameter” may cheat you

An another weekend!..

It has been a long time i am thinking to write an interesting article on C# programming. Here is an interesting post on Named Parameter, the thread is from a technical discussion happned between my collegue jameel and me 🙂

Let’s look into this sample

 class Program
    {
        static void Main(string[] args)
        {
            var man = new Man();
            var human = (Human)man;
            man.Calculate(x: 1, y: 2);
            human.Calculate(x: 1, y: 2);
            Console.ReadKey();
        }

        public class Human
        {
            public virtual void Calculate(int x, int y)
            {
                Console.WriteLine("Human Calculating X :{0} and Y:{1}", x, y);
            }
        }
        public class Man : Human
        {
            public override void Calculate(int y, int x)
            {
                Console.WriteLine("Man Calculating X :{0} and Y:{1}", x, y);
            }
        }
    }

The lines highligted as red would call the “Calculate” method of both Human and Man object which prints the values x and y respectively.

What would be the output?  Can you guess a little? 🙂

"Man Calculating X :1 and Y:2"
"Man Calculating X :1 and Y:2"

If your answer resulted as above, then i am sorry :(. It’s absolutly wrong… You have cheated by Named Parameter :). The correct answer is

"Man Calculating X :1 and Y:2"
"Man Calculating X :2 and Y:1"

Now you might be thinking, what the hell this guy is talking?.

Dont’ know… sometimes i may be like this. moreover programming is a fun. Let’s talk why it’s happening like this.

Argument binding for the method call Human.Calculate(x: 1, y: 2) is done at compile time, but method dispatch is done at runtime because the method is virtual.

In order to compile the method call, the compiler sees x: 1, y: 2 and needs to resolve this named argument list to a sequentially indexed argument list in order to emit the appropriate IL (push the arguments on the stack in the right order, then call method).

In addition to the named argument list there is one more piece of information available to the compiler: the type of human, which is Human. Now me and you both know that at runtime this is going to be a Man instance, but the compiler doesn’t know that. So it looks up the parameter list of human.Calculate and sees that x is the first argument, y is the second. This makes it compile your code as if you had written

human.Calculate(1, 2);

At runtime, the arguments 1 and 2 are pushed on the stack and a virtual call is made to Calculate. Of course this ends up calling Man.Calculate, but the parameter names have not survived the transition to runtime. Man.Calculate accepts 1 as its first argument (y) and 2 as its second argument (x), leading to the observed result.

As an aside, this is also what happens when you use default argument values.

Advertisement

One thought on “Beware : Some times “Named Parameter” may cheat you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s