스파르타입니까?
다음은 면접 질문입니다. 나는 해결책을 찾았지만 그것이 왜 효과가 있는지 잘 모르겠습니다.
질문:
Sparta
클래스를 수정하지 않고 MakeItReturnFalse
return 을 만드는 코드를 작성하십시오 false
.
public class Sparta : Place
{
public bool MakeItReturnFalse()
{
return this is Sparta;
}
}
내 솔루션 : (SPOILER)
public class Place
{
public interface Sparta { }
}
그러나 왜 대신 Sparta
에 MakeItReturnFalse()
언급 합니까?{namespace}.Place.Sparta
{namespace}.Sparta
그러나 왜 대신
Sparta
에MakeItReturnFalse()
언급 합니까?{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)에 대해 해당 유형 선언의 인스턴스 유형으로 시작하여 각 클래스의 인스턴스 유형으로 계속 또는 구조체 선언 (있는 경우) :
- 경우
K
0이고 선언의T
이름의 입력 매개 변수를 포함하고I
, 그 공간 또는 타입 이름은 입력 파라미터를 지칭한다. [아니]- 그렇지 않으면, namespace-or-type-name이 유형 선언의 본문 내에 나타나
T
거나 기본 유형 중 하나에 이름I
및K
유형 매개 변수 가있는 중첩 액세스 가능한 유형이 포함 된 경우 namespace-or-type-name 은 주어진 타입 인자로 구성된 타입. [빙고!]- 이전 단계가 실패한 경우, 각 네임 스페이스에 대해 네임 스페이스
N
또는 유형 이름이 발생하는 네임 스페이스 로 시작하고, 포함하는 각 네임 스페이스 (있는 경우)로 계속하고 글로벌 네임 스페이스로 끝나는 경우 다음 단계가 평가됩니다. 엔티티가 위치 할 때까지 :
- 경우
K
0이고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 thePlace
superclass to illustrate interface name resolution. - Let's also print out the type name of
this
as it is bound in theSparta
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
'Programing' 카테고리의 다른 글
C ++에서 "const"는 몇 개나 어떤 것입니까? (0) | 2020.07.13 |
---|---|
문화와 UICulture의 차이점은 무엇입니까? (0) | 2020.07.13 |
암호화 / 암호 보호 기능이있는 SQLite (0) | 2020.07.13 |
실행시에만 알려진 형식 인수로 일반 메서드 호출 (0) | 2020.07.13 |
ASP.NET 웹 API 인증 (0) | 2020.07.13 |