19

Without running this code, identify which Foo method will be called:

class A
{
   public void Foo( int n )
   {
      Console.WriteLine( "A::Foo" );
   }
}

class B : A
{
   /* note that A::Foo and B::Foo are not related at all */
   public void Foo( double n )
   {
      Console.WriteLine( "B::Foo" );
   }
}

static void Main( string[] args )
{
   B b = new B();
   /* which Foo is chosen? */
   b.Foo( 5 );
}

Which method? And why? No cheating by running the code.

I found this puzzle on the web; I like it and I think I'm going to use it as an interview question...Opinions?

EDIT: I wouldn't judge a candidate on getting this wrong, I'd use it as a way to open a fuller discussion about the C# and CLR itself, so I can get a good understanding of the candidates abilities.

Source: http://netpl.blogspot.com/2008/06/c-puzzle-no8-beginner.html

FlySwat
  • 172,459
  • 74
  • 246
  • 311
  • 35
    If someone asks me that, I'll say, you should have written the Main method in a class :)) – Mehrdad Afshari Jan 23 '09 at 12:39
  • Can someone explain, why do it call base class method when we change type of parameter from int to double(A.Foo) and double to int(B.Foo) and pass input as double? – Akash KC May 14 '13 at 05:43

15 Answers15

57

I really wouldn't use this as an interview question. I know the answer and the reasoning behind it, but something like this should come up so rarely that it shouldn't be a problem. Knowing the answer really doesn't show much about a candidate's ability to code.

Note that you'll get the same behaviour even if A.Foo is virtual and B overrides it.

If you like C# puzzles and oddities, I've got a few too (including this one).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I noticed there's an answer down there that present the problem of interviewees getting questions right for the wrong reasons. I proposed that design questions should be more focused than trivia. You can always read a compiler issue, or figure a bug out, but bad design takes much longer to fix. (Just bringing these up, because they enhance this answer and are lost in the sludge). – Lee Louviere Jan 25 '12 at 17:23
  • This is why implicit casting of unrelated types sucks :) – tymtam Jul 03 '12 at 14:36
  • An old question but got confused with one part,Why do it call base class method when we change type of parameter from int to double(A.Foo) and double to int(B.Foo) and pass input as double(b.Foo(5.8))? – Akash KC May 14 '13 at 05:58
26

Too hard? No, but what is your goal in the question? What are you expecting to get from your interviewee? That they know this particular syntactic quirk? That either means that they've studied the spec/language well (good for them) or that they've run into this problem (hopefully not from what they wrote, but if they did - yikes). Neither case really indicates that you've got a solid programmer/engineer/architect on your hand. I believe that what's important is not the question but the discussion surrounding the question.

When I interview candidates, I usually ask one deceptively simple question which is based on a language semantic quirk - but I don't care if my interviewee knows it because that semantic quirk allows me to open up a lot of avenues that allow me to find out if my candidate is methodical, their communication style, if they're willing to say "I don't know", are they capable of thinking on their feet, do they understand language design and machine architecture, do they understand platform and portability issues - in short, I'm looking for a lot of ingredients that all add up to "do they get it?". This process takes an hour or more.

In the end, I don't actually care about whether they know the answer to my question - the question is a ruse to let me get all the rest of that information indirectly without ever having to ask. If you don't have a valuable ulterior in this question, don't bother even asking it - you're wasting your time and your candidate's time.

plinth
  • 48,267
  • 11
  • 78
  • 120
  • 3
    Best interviewer I've encountered quizzed me for a couple hours on C# questions knowing that I don't know C# (but I do know java and C++). I got an offer based on my ability to reason the most likely answers – tloach Sep 30 '08 at 19:05
12

Couldn't agree more with Joel there. I have 20+ years experience design and coding, and the first thing I thought of when I saw that was: It won't even compile.

I made that assumption because I try to avoid overloads that differ by only a single datatype, and in looking at the code didn't even pick up on the int/double difference; I assumed there needed to be a new operator to allow a redefinition in B.

In point of fact I had used a library a fellow programmer created for handling some text file generation that was a bit confusing because one of the methods had 8 different overloads and two of them differed only by datatype on the last argument. One was string and one was char. The likelihood that the value needed for the string version of the parameter was one character long was pretty good so hopefully you can see where this is headed. We had a devil of a time debugging problems because the consumer of the library inadvertently triggered the wrong call because of quoting differences, single versus double.

Moral of the story, be grateful that the candidate doesn't know the answer because it may indicate good coding habits.

Bill
  • 1,738
  • 10
  • 22
  • 1
    It sounds like you don't do a lot of inheritance in your design. Overloading methods of the same name that differ by a parameter type isn't uncommon. – mmcdole Sep 30 '08 at 20:00
  • I too, just like you Bill, prefer a programmer who would say "I never stumbled upon such a case before" than one that would know the answer right away. – Andrei Rînea Sep 30 '08 at 21:55
  • Simucal, we do a great deal of inheritance. I'm not sure why method overloading would be considerd a hallmark of inheretance. Maybe you are referring more to operator overloads and not method overloads, which we do a great deal of and are more clearly recognizable in code with the operator keyword. – Bill Oct 02 '08 at 22:47
  • In my experience, operator overloads are a code smell, and a huge one at that. Method overloads are pretty common, especially for convenience. – Robert C. Barth Mar 04 '10 at 18:25
10

Another vote against using it, but for a different reason.

When put on the spot like this, a lot of really good programmers would come up with the wrong answer, but not because they don't know the concepts or couldn't figure it out. What happens is that they'll see something like this and think, "Aha, trick question!", and then proceed to out-think themselves in the response. This is especially true in an interview setting where they don't have the benefit of the IDE or Google or any other of the other helps a programmer takes for granted in their day to day programming.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
7

Console.WriteLine( "B::Foo");

Because it will cast automatictly and use the first without going further in the inheritance.

I do not think it's a good interview question but it can be funny to try to solve without compiling the code.

Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
  • Only if it can cast without losing precision, such as int -> double, if they were reversed, it would call the base method. – FlySwat Sep 30 '08 at 17:41
  • You are right. The example is with 5 so nothing in the precision is lost :) – Patrick Desjardins Sep 30 '08 at 17:42
  • The CS geek in me is crying. You *DO* lose precision when you convert int->double. A double does not exactly represent an integer, if you were to continually multiply the double by 10 eventually you would see errors creep in. – tloach Sep 30 '08 at 19:03
  • That's not really the same as losing precision - you lose nothing converting int to double and back again. If you then do some maths with that double you'll get back something else. – Keith Oct 02 '08 at 12:30
7

Not really fair as an interview question, as it's a bit of a trick question. The good answer I'd want from an interviewee would be more along the lines of "That needs refactoring".

Unless you're looking to hire someone to work on compilers I'm not sure that you need to go that much in depth into the CLR.

For interview questions I look for things that show the coder's level of understanding in their answer. This is more of an oddity/puzzle.

Keith
  • 150,284
  • 78
  • 298
  • 434
  • Yours is the best answer. When faced with such a question I would try to find an answer but ultimately express my opinion that it is a bad practice to have such puzzles in code and opt for another solution. –  Oct 23 '09 at 08:33
6

This actually is a trick question.

The answer is ambiguous as to what "should" happen. Sure, the C# compiler takes it out of the realm of ambiguity to the concrete; however, since these methods are overloading one another, and are neither overriding nor shadowing, it is reasonable to assume that the "best argument fit" should apply here, and therefore conclude that it is A::Foo(int n) that should be called when provided an integer as an argument.

To prove that what "should" happen is unclear, the exact same code when run in VB.NET has the opposite result:

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles Button1.Click
        Dim b As New B
        b.Foo(5)   ' A::Foo
        b.Foo(5.0) ' B::Foo
    End Sub
End Class

Class A
    Sub Foo(ByVal n As Integer)
        MessageBox.Show("A::Foo")
    End Sub
End Class

Class B
    Inherits A

    Overloads Sub Foo(ByVal n As Double)
        MessageBox.Show("B::Foo")
    End Sub
End Class

I realize that I am opening up the opportunity for the C# programmers to "bash" VB.NET for not complying with C# . But I think one could make a very strong argument that it is VB.NET that is making the proper interpretation here.

Further, IntelliSense within the C# IDE suggests that there are two overloads for the class B (because there are, or at least should be!), but the B.Foo(int n) version actually can't be called (not without first explicitly casting to a class A). The result is that the C# IDE is not actually in synch with the C# compiler.

Another way of looking at this is that the C# compiler is taking an intended overloads and turning it into a shadowed method. (This doesn't seem to be the right choice to me, but this is obviously just an opinion.)

As an interview question, I think that it can be ok if you are interested in getting a discussion about the issues here. As for getting it "right" or "wrong", I think that the question verges on a trick question that could be easily missed, or even gotten right, for the wrong reasons. In fact, what the answer to the question "should be" is actually very debatable.

Mike Rosenblum
  • 12,027
  • 6
  • 48
  • 64
  • 1
    +1 for getting it right for the wrong reasons. This is why trivia is so bad. You get an idiot that looks good on paper. Better to ask design questions. – Lee Louviere Jan 25 '12 at 17:20
3

I think it's a terrible question. I think any question is a terrible question when the real answer is "Run it and see!"

If I needed to know this in real life, that's exactly what I'd do: Create a test project, key it in, and find out. Then I don't have to worry about abstract reasoning or the finer points in the C# spec.

Just today I ran into such a question: If I fill the same typed DataTable twice with the same row, what will happen? One copy of the row, or two? And will it overwrite the first row even if I've changed it? I thought about asking someone, but I realized I could easily fire up a test project I already had that used DataSets, write a small method, and test it out.

Answer:

...ah, but if I tell you, you'll miss the point. :) The point is, in programming you don't have to leave these things as hypotheticals, and you shouldn't if they can be reasonably tested.

So I think it's a terrible question. Wouldn't you prefer to hire a developer who'll try it out and then know what happens, rather than a developer who'll try to dredge it up from his fading memory, or who'll ask someone else and accept an answer that might be wrong?

Ryan Lundy
  • 204,559
  • 37
  • 180
  • 211
  • I don't think "run it and see" is all there is to it. There exist code snippets which give different results on different compiler/runtime versions (although this isn't one of them). "It worked on my machine" isn't an ideal position to take when my code fails further down the line. – Steve Jessop Oct 22 '08 at 21:56
  • My usual approach would be first to run it to see what I get, and then with that knowledge to examine the specification to see whether what I got is guaranteed to happen always. – Steve Jessop Oct 22 '08 at 22:01
  • 1
    And yet...you can also "run it and see" on those other compilers or versions! And if "it works on my machine" isn't sufficient, that's obviously because when you "run it and see" on someone else's machine, it doesn't work. Ultimately real-world testing will always trump theory. – Ryan Lundy Oct 24 '08 at 18:17
3

That's a ridiculous question to ask - I could answer it in < 60 seconds with Snippet Compiler, and if I ever worked in a code base that depended on the functionality - it'd be quickly refactored out of existence.

The best answer is "that's a stupid design, don't do that and you won't have to parse the language spec to know what it's going to do".

If I was the interviewee, I'd think very highly of your geek trivia cred, and would perhaps invite you to the next game of Geek Trivial Pursuit. But, I'm not so sure I'd want to work with/for you. If that's your goal, by all means ask away.

  • Note that in an informal situation, geek trivia like this can be fun and entertaining. But, to an interviewee, an interview is anything but fun or informal - why further agitate it with trivial questions that the interviewee doesn't know if you take seriously or not?
Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
  • So your answer is basically that it doesn't matter if someone knows how their programming language works? – BobbyShaftoe Dec 30 '08 at 18:01
  • 1
    @Bobby - at the extreme edges? Yeah, I'd say it doesn't really matter. I'd much rather someone who can reason, than a spec geek. – Mark Brackett Dec 30 '08 at 22:33
  • @BobbyShaftoe Good programmers can learn idiosyncrasies of a language. You have X time in an interview. It's best to focus on whether you have a good programmer, rather than a guy that can spot compiling issues. I'd rather a guy come up with a good design for a house, rather than a guy that won't ever accidentally select the wrong screw for a split second, and build an unusable house. – Lee Louviere Jan 25 '12 at 17:14
2

This smacks of a trick question to me. If you've been using the language for long enough, you've probably run into the problem and know the answer; but how long is long enough?

It's also a question where your background might work against you. I know in C++ the definition in B would hide the definition in A, but I have no idea if it works the same in C#. In real life, I'd know it was a questionable area and try to look it up. In an interview I might try to guess, having been put on the spot. And I'd probably get it wrong.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

use it as a question only as long as you expect the candidate to tell you his thought processes as he describes what he thinks should be happening. Who cares about the right and wrongness of actual code in question - in the real world, the candidate would find code like this, find it not working and debug it with a combination of debugger and writeline calls, so its a useless question if you want candidates who know (or guess) the right answer.

But those who can explain what they think would happen, that's a different matter. Hire them even if they get it wrong.

gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
2

It takes all of 5 seconds in a real work situation to figure out what went wrong. Compile, test, oops.

I'm far more concerned on if someone can build good and maintainable code. Ask questions like

  • How would you design for this, write simple abstract design, no code.
  • Here's an object design. The customer came and said they wanted this. Formulate a new design -or- discuss reasons why the requirements don't fulfill actual customer needs.
Lee Louviere
  • 5,162
  • 30
  • 54
0

As many have already stated, when I interview someone I want to find out if the candidate is capable of communicating, capable of writing code which makes sense and it can be easily understood by others, code which can be maintained and so forth. I personally don't like to spend time in exercises like the one proposed. Instead I'd rather give an exercise where the candidate will write code him/herself - even in a regular text editor - and from there opening a discussion based on code review, improvements as so forth. No need the code to compile: compiler will do its job, eventually. I know many people may disagree on this approach, but so far I have found this the best way of finding good candidates.

beltry
  • 73
  • 1
  • 3
0

Code given in question will print B::Foo.

andr
  • 15,970
  • 10
  • 45
  • 59
Anwar
  • 1
  • 2
    Your answer would be much more valuable if you included your suspicions about *why* this particular method will get called. – andr Jan 08 '13 at 15:26
0

Try a similar sample given below:

class Program
{
    class P
    {}
    class Q : P
    {}

    class A 
    { 
        public void Fee(Q q)
        {
            Console.WriteLine("A::Fee");
        }
    }

    class B : A 
    {   
        public void Fee(P p)
        {
            Console.WriteLine("B::Fee");
        }
    }

    static void Main(string[] args) 
    { 
        B b = new B();   
        /* which Fee is chosen? */  

        b.Fee(new Q());
        Console.ReadKey();
    }
}

The compiler seems to prefer linking the "b.Fee()" call to an available method of the type rather than an inherited method (method of a base type) if the parameter can be implicitly cast to match any such method. I.e. implicit casting of the parameter takes precedence over base class method linking.

Though honestly I find the opposite as more intuitive, because for me an inherited method is just as good as a directly introduced method.