Programing

스파르타입니까?

crosscheck 2020. 7. 13. 20:34
반응형

스파르타입니까?


다음은 면접 질문입니다. 나는 해결책을 찾았지만 그것이 왜 효과가 있는지 잘 모르겠습니다.


질문:

Sparta클래스를 수정하지 않고 MakeItReturnFalsereturn 을 만드는 코드를 작성하십시오 false.

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

내 솔루션 : (SPOILER)

public class Place
{
public interface Sparta { }
}

그러나 왜 대신 SpartaMakeItReturnFalse()언급 합니까?{namespace}.Place.Sparta{namespace}.Sparta


그러나 왜 대신 SpartaMakeItReturnFalse()언급 합니까?{namespace}.Place.Sparta{namespace}.Sparta

기본적으로 이름 조회 규칙이 말하는 것이기 때문입니다. C # 5 사양에서 관련 명명 규칙은 섹션 3.8 ( "네임 스페이스 및 유형 이름")에 있습니다.

글 머리 기호 및 주석 처리 된 첫 번째 글 머리 기호 :

  • namespace-or-type-name이 다음과 같은 형식 I또는 형식 인 경우 I<A1, ..., AK> [우리의 경우 K = 0] :
    • K가 0이고 namespace-or-type-name이 일반 메소드 선언 내에 나타나는 경우 [nope, no generic methods]
    • 그렇지 않으면, namespace-or-type-name이 유형 선언 내에 나타나면, 각 유형의 T (§10.3.1)에 대해 해당 유형 선언의 인스턴스 유형으로 시작하여 각 클래스의 인스턴스 유형으로 계속 또는 구조체 선언 (있는 경우) :
      • 경우 K0이고 선언의 T이름의 입력 매개 변수를 포함하고 I, 그 공간 또는 타입 이름은 입력 파라미터를 지칭한다. [아니]
      • 그렇지 않으면, namespace-or-type-name이 유형 선언의 본문 내에 나타나 T 거나 기본 유형 중 하나에 이름 IK유형 매개 변수 가있는 중첩 액세스 가능한 유형이 포함 된 경우 namespace-or-type-name 은 주어진 타입 인자로 구성된 타입. [빙고!]
  • 이전 단계가 실패한 경우, 각 네임 스페이스에 대해 네임 스페이스 N또는 유형 이름이 발생하는 네임 스페이스 로 시작하고, 포함하는 각 네임 스페이스 (있는 경우)로 계속하고 글로벌 네임 스페이스로 끝나는 경우 다음 단계가 평가됩니다. 엔티티가 위치 할 때까지 :
    • 경우 K0이고 I있는 네임 스페이스의 이름입니다 N, 다음 ... [예, 그 것이다 성공]

마지막 글 머리 기호 는 첫 번째 글 머리 기호가 없으면 Sparta 클래스를 선택하는 것입니다 ...하지만 기본 클래스 Place가 인터페이스를 정의 하면 클래스를 고려 하기 전에Sparta 발견 됩니다 .Sparta

중첩 형식을 Place.Sparta인터페이스가 아닌 클래스로 만들면 여전히 컴파일되어 반환 false되지만 컴파일러 Sparta는의 인스턴스가 클래스 의 인스턴스가 될 수 없다는 것을 알고 있으므로 경고를 표시 합니다 Place.Sparta. 마찬가지로 Place.Sparta인터페이스 를 유지 하면서 Sparta클래스 sealed를 만들면 Sparta인터페이스를 구현할 수있는 인스턴스가 없으므로 경고가 표시 됩니다.


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.


Beautiful question! I'd like to add a slightly longer explanation for those who don't do C# on a daily basis... because the question is a good reminder of name resolution issues in general.

Take the original code, slightly modified in the following ways:

  • Let's print out the type names instead of comparing them as in the original expression (i.e. return this is Sparta).
  • Let's define the interface Athena in the Place superclass to illustrate interface name resolution.
  • Let's also print out the type name of this as it is bound in the Sparta class, just to make everything very clear.

The code looks like this:

public class Place {
    public interface Athena { }
}

public class Sparta : Place
{
    public void printTypeOfThis()
    {
        Console.WriteLine (this.GetType().Name);
    }

    public void printTypeOfSparta()
    {
        Console.WriteLine (typeof(Sparta));
    }

    public void printTypeOfAthena()
    {
        Console.WriteLine (typeof(Athena));
    }
}

We now create a Sparta object and call the three methods.

public static void Main(string[] args)
    {
        Sparta s = new Sparta();
        s.printTypeOfThis();
        s.printTypeOfSparta();
        s.printTypeOfAthena();
    }
}

The output we get is:

Sparta
Athena
Place+Athena

However, if we modify the Place class and define the interface Sparta:

   public class Place {
        public interface Athena { }
        public interface Sparta { } 
    }

then it is this Sparta -- the interface -- that will be available first to the name lookup mechanism and the output of our code will change to:

Sparta
Place+Sparta
Place+Athena

So we have effectively messed up with the type comparison in the MakeItReturnFalse function definition just by defining the Sparta interface in the superclass, which is found first by the name resolution.

But why does C# chose to prioritize interfaces defined in the superclass in the name resolution? @JonSkeet knows! And if you read his answer you'll get the details of the name resolution protocol in C#.

참고URL : https://stackoverflow.com/questions/44120947/this-is-sparta-or-is-it

반응형