ildasm 및 C # 프로그램 사용 예
static void Main(string[] args)
{
}
제공합니다 :
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::Main
hidebysig 구조는 무엇을합니까?
답변
에서 ECMA 335 , 파티션 1의 섹션 8.10.4 :
CTS는 기본 유형에서 표시되는 이름 (숨기기)과 파생 클래스의 레이아웃 슬롯 공유 (재정의) 모두에 대한 독립적 인 제어를 제공합니다. 숨기기는 파생 클래스의 멤버를 이름으로 숨기기 또는 이름 및 서명으로 숨기기로 표시하여 제어됩니다. 숨기기는 항상 멤버의 종류에 따라 수행됩니다. 즉, 파생 필드 이름은 기본 필드 이름을 숨길 수 있지만 메서드 이름, 속성 이름 또는 이벤트 이름은 숨길 수 없습니다. 파생 멤버가 이름으로 숨기기로 표시되면 동일한 이름을 가진 기본 클래스에서 동일한 종류의 멤버가 파생 클래스에 표시되지 않습니다. 멤버가 이름 및 서명으로 숨기기로 표시되면 정확히 동일한 이름 및 유형 (필드의 경우) 또는 메서드 서명 (메서드의 경우)을 가진 동일한 종류의 멤버 만 파생 클래스에서 숨겨집니다. 이 두 가지 형태의 은폐를 구분하는 구현은 전적으로 소스 언어 컴파일러와 리플렉션 라이브러리에 의해 제공됩니다. VES 자체에는 직접적인 영향을주지 않습니다.
(즉시 명확하지는 않지만 hidebysig
“이름 및 서명으로 숨기기”를 의미합니다.)
또한 파티션 2의 섹션 15.4.2.2에서 :
hidebysig는 도구 사용을 위해 제공되며 VES에서 무시됩니다. 선언 된 메서드가 메서드 시그니처가 일치하는 기본 클래스 형식의 모든 메서드를 숨기도록 지정합니다. 생략하면 서명에 관계없이 동일한 이름의 모든 메서드를 숨겨야합니다.
예를 들어 다음이 있다고 가정합니다.
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
때문에 즉, 유효입니다 Bar(string)
하지 않습니다 숨기기 Bar()
때문에 C # 컴파일러의 사용, hidebysig
. “hide by name”의미론을 사용했다면 , 여전히 Base로 캐스트하고 그렇게 호출 할 수는 있지만 Bar()
type 참조에 대해 전혀 호출 할 수 없습니다 Derived
.
편집 : 위의 코드를 DLL로 컴파일하고 ildasming하고 hidebysig
for Bar()
및을 제거 Bar(string)
하고 다시 ilasming 한 다음 Bar()
다른 코드에서 호출하려고 시도했습니다 .
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments
하나:
Base d = new Derived();
d.Bar();
(컴파일 문제가 없습니다.)
답변
THE SKEET의 답변에 따라 그 이유는 Java 및 C #이 클래스의 클라이언트가 기본 클래스의 메서드를 포함하여 동일한 이름을 가진 모든 메서드를 호출 할 수 있도록 허용하기 때문입니다. C ++는 그렇지 않은 반면, 파생 클래스가 기본 클래스의 메서드와 이름이 같은 단일 메서드도 정의하면 동일한 인수를 사용하지 않더라도 클라이언트가 기본 클래스 메서드를 직접 호출 할 수 없습니다. 따라서이 기능은 오버로딩에 대한 두 가지 접근 방식을 모두 지원하기 위해 CIL에 포함되었습니다.
C ++에서는 using
지시문 을 사용하여 기본 클래스에서 명명 된 오버로드 집합 하나를 효과적으로 가져올 수 있으므로 해당 메서드 이름에 대한 “오버로드 집합”의 일부가됩니다.
답변
Microsoft Docs 에 따르면
파생 클래스의 멤버가 C #
new
수정 자 또는 Visual BasicShadows
수정 자를 사용하여 선언 되면 기본 클래스에서 동일한 이름의 멤버를 숨길 수 있습니다. C #은 기본 클래스 멤버를 서명으로 숨 깁니다. 즉, 기본 클래스 멤버에 여러 오버로드가있는 경우 숨겨진 유일한 항목은 동일한 서명을 가진 항목입니다. 반대로 Visual Basic은 모든 기본 클래스 오버로드를 숨 깁니다. 따라서 IsHideBySig
는false
Visual BasicShadows
수정 자로true
선언 된 멤버와 C #new
수정 자로 선언 된 멤버에 대해 반환합니다 .