When is a giraffe not a giraffe?

23

6

I hope this kind of "riddle" is ontopic in Programming Puzzles & Code Golf.

Give an example of a situation where the C# method below returns false:

public class Giraffe : Animal
{
  public bool Test()
  {
    return this is Giraffe;
  }
}

Rules: The code lines above must not be changed in any way, but you would put the code into an application so that the "project" compiles and the method is called. When run, the method must return false. The solution I have in mind, does not emit its own IL at run-time or similar "exotic" things, it's an ordinary instance method call.

Jeppe Stig Nielsen

Posted 2013-08-01T15:58:55.333

Reputation: 602

2By "the method is called", do you mean to say that Giraffe giraffe = new Giraffe(); giraffe.Test(); must occur somehow so that the line in that method is, in fact, executed? – Jesse C. Slicer – 2013-08-02T15:22:40.240

@JesseC.Slicer Yes, in the solution I have in mind, that line does occur. Of course, it could be interesting to see other solutions that I haven't thought of, too. So if you have something, do post it! – Jeppe Stig Nielsen – 2013-08-02T15:25:23.517

1Well, my simple solution looks more like Animal giraffe = new Giraffe(); giraffe.Test(); and the parent class Animal has a Test() method which returns false. That's cheating a bit as it calls the parent class method rather than Giraffe's. But the call site looks the same. – Jesse C. Slicer – 2013-08-02T15:28:23.917

@JesseC.Slicer Ah, I see. I would argue that with your "solution" it is not the "method below" (as it says in my problem) that returns false, so I wouldn't say it was a full solution. But interesting still. My solution does not have any *method* hiding (hint), but as I said, other solutions could be interesting too. – Jeppe Stig Nielsen – 2013-08-02T15:32:27.233

Answers

28

Yay, found it!

public class Animal
{
    public class Giraffe { } // 1
}
public class Giraffe : Animal // 2
{
    public bool Test()
    {
        return this is Giraffe;
    }
}

Since Giraffe 1 is a member of Animal, and Giraffe 2 is one level further out, the name Giraffe in the is test refers to the former (section 7.6.2 in the C# 5 spec).

Visual Studio shows a warning for this is Giraffe:

The given expression is never of the provided type

which is obviously true, since it's the whole point :)

You cannot put Giraffe 1 directly inside Giraffe 2, because

member names cannot be the same as their enclosing type

– but such a rule does not exist for derived classes.

Neat problem, took me a while.

balpha

Posted 2013-08-01T15:58:55.333

Reputation: 591

11Well played sir – Marc Gravell – 2013-08-02T18:53:51.450

2Yes, this was the solution I had in mind! So there are two types, one nested TheNamespace.Animal.Giraffe which because of inheritance can also be called TheNamespace.Giraffe.Giraffe, and one non-nested TheNamespace.Giraffe. Your reference to the C# spec is relevant! You can get rid of the compiler warning. Just change the nested type of the base class from class to interface. In that case someone might derive further from the non-nested Giraffe and implement the nested Giraffe as well, so in that case the compiler can't complain; it's a "fair" type check. – Jeppe Stig Nielsen – 2013-08-03T06:27:21.287

1I don't understand this solution — that may be because I don't know C# much. I don't like this playing on names. I find the solution of @JesseC.Slicer much cleverer. – Nicolas Barbulesco – 2014-05-30T13:01:53.010