Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

This is Sparta, or is it?

The following is an interview question. I came up with a solution, but I'm not sure why it works.


Question:

Without modifying the Sparta class, write some code that makes MakeItReturnFalse return false.

public class Sparta : Place
{
    public bool MakeItReturnFalse()
    {
        return this is Sparta;
    }
}

My solution: (SPOILER)

public class Place
{
public interface Sparta { }
}

But why does Sparta in MakeItReturnFalse() refer to {namespace}.Place.Sparta instead of {namespace}.Sparta?

like image 555
budi Avatar asked Oct 07 '22 21:10

budi


People also ask

What is the quote This is Sparta from?

300 (1/5) Best Movie Quote - This is Sparta!

What is this is Sparta?

This is SPARTA! is a 2007 meme that originated from a scene from the movie "300" in which Leonidas, the leader of the Spartans, kicks a persian messenger into a hole.

Who is the guy that says this is Sparta?

Gerard Butler Says Unexpected Delivery of Iconic '300' Line Made Cast Laugh. In a GQ video posted Monday, actor Gerard Butler explains when he screamed the iconic '300' line "This is Sparta!" that his army almost broke character laughing.

Who says this is Sparta in 300?

Gerard Butler's tense standoff with a messenger is one of the most memorable moments in 300. In the scene, his character, King Leonidas, shouts “This is Sparta!” before kicking him into a pit of darkness.


2 Answers

But why does Sparta in MakeItReturnFalse() refer to {namespace}.Place.Sparta instead of {namespace}.Sparta?

Basically, because that's what the name lookup rules say. In the C# 5 specification, the relevant naming rules are in section 3.8 ("Namespace and type names").

The first couple of bullets - truncated and annotated - read:

  • If the namespace-or-type-name is of the form I or of the form I<A1, ..., AK> [so K = 0 in our case]:
    • If K is zero and the namespace-or-type-name appears within a generic method declaration [nope, no generic methods]
    • Otherwise, if the namespace-or-type-name appears within a type declaration, then for each instance type T (§10.3.1), starting with the instance type of that type declaration and continuing with the instance type of each enclosing class or struct declaration (if any):
      • If K is zero and the declaration of T includes a type parameter with name I, then the namespace-or-type-name refers to that type parameter. [Nope]
      • Otherwise, if the namespace-or-type-name appears within the body of the type declaration, and T or any of its base types contain a nested accessible type having name I and K type parameters, then the namespace-or-type-name refers to that type constructed with the given type arguments. [Bingo!]
  • If the previous steps were unsuccessful then, for each namespace N, starting with the namespace in which the namespace-or-type-name occurs, continuing with each enclosing namespace (if any), and ending with the global namespace, the following steps are evaluated until an entity is located:
    • If K is zero and I is the name of a namespace in N, then... [Yes, that would succeed]

So that final bullet point is what picks up the Sparta class if the first bullet doesn't find anything... but when the base class Place defines an interface Sparta, it gets found before we consider the Sparta class.

Note that if you make the nested type Place.Sparta a class rather than an interface, it still compiles and returns false - but the compiler issues a warning because it knows that an instance of Sparta will never be an instance of the class Place.Sparta. Likewise if you keep Place.Sparta an interface but make the Sparta class sealed, you'll get a warning because no Sparta instance could ever implement the interface.

like image 74
Jon Skeet Avatar answered Oct 09 '22 17:10

Jon Skeet


When resolving a name to its value the "closeness" of the definition is used to resolve ambiguities. Whatever definition is "closest" is the one that is chosen.

The interface Sparta is defined within a base class. The class Sparta is defined in the containing namespace. Things defined within a base class are "closer" than things defined in the same namespace.

like image 23
Servy Avatar answered Oct 09 '22 19:10

Servy