.NET의 대표단 : 어떻게 건설됩니까?
-
19-09-2019 - |
문제
일반적으로 C# 및 .NET에서 대의원을 검사하는 동안 흥미로운 사실을 알았습니다.
C#에서 대의원 생성에서 파생 된 클래스가 생성됩니다. MulticastDelegate
생성자로 :
.method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed { }
인스턴스와 메소드에 대한 포인터를 기대합니다. 그러나 C#에서 대의원을 구성하는 구문은 생성자가 있음을 시사합니다.
new MyDelegate(int () target)
내가 알아볼 수있는 곳 int ()
함수 인스턴스 (int *target()
C ++의 함수 포인터입니다). 따라서 C# 컴파일러는 기능 이름으로 정의 된 메소드 그룹에서 올바른 메소드를 선택하고 대의원을 구성합니다. 첫 번째 질문은 C# 컴파일러 (또는 Visual Studio) 가이 생성자 서명을 선택하는 곳은 어디입니까? 나는 특별한 속성이나 구별 할 무언가를 눈치 채지 못했습니다. 이것은 일종의 컴파일러/VisualStudio Magic입니까? 그렇지 않은 경우입니다 T (args) target
C#에서 유효한 건축? 나는 컴파일하기 위해 그것과 아무것도 얻지 못했습니다.
int () target = myMethod;
유효하지 않으므로 무엇이든하고 있습니다 MyMetod
, 예를 들어 전화 .ToString()
그것에 (글쎄, 이것은 기술적으로 방법이기 때문에 이것은 의미가 있습니다. 그룹, 그러나 나는 캐스팅을 통해 방법을 명시 적으로 선택할 수 있다고 생각합니다. (int())MyFunction
. 이 모든 컴파일러 마법입니까? 리플렉터를 통해 구조를 살펴보면 또 다른 구문이 나타납니다.
func cs $ 1 $ 0000 = 새로운 func (null, (intptr) foo);
이것은 분해 된 생성자 서명과 일치하지만 컴파일되지 않습니다!
마지막 흥미로운 메모는 수업입니다 Delegate
그리고 MulticastDelegate
또 다른 세트의 생성자가 있습니다.
.method family hidebysig specialName rtspecialName instance void .ctor (class system.type target, String 'method') cil 관리
인스턴스 및 메소드 포인터에서 유형 및 문자열 메소드 이름으로의 전환은 어디에 있습니까? 이것은 설명 할 수 있습니다 runtime managed
사용자 정의 대의원 생성자 서명의 키워드, 즉 런타임이 여기에서 작업을 수행합니까?
편집하다: 좋아, 그래서 나는이 질문으로 내가 말하고 싶은 것을 재구성해야한다고 생각한다. 기본적으로 C# Compiler / CLR Magic뿐만 아니라 대의원뿐만 아니라 일부가 있다고 제안합니다. 비주얼 스튜디오 Magic, IntelliSense는 생성자 인수를 제안 할 때 새로운 구문을 뒤집어 놓고 그 중 하나를 숨기므로 (예 : 반사판은이 구문과 아축자를 사용하지 않습니다.
이 어설 션이 사실인지, 그리고 함수 인스턴스 구문이 C#에서 더 깊은 의미를 갖는지 또는 명확성을 위해 Visual Studio Magic Part에 의해 구현 된 일정한 형식 일뿐입니다. 요컨대, 내가 Intellisense를 구현한다면, 대의원을 위해 마술을해야합니까, 아니면 영리한 메커니즘으로 제안을 구성 할 수 있습니까?
최종 편집: 그래서 대중적인 합의는 그것이 실제로 마술과 마술이라는 것입니다. 그러한 행동과 행동에 대한 다른 예 (Marc Gravell의 의견 참조)를 보면 그것이 사실이라고 확신합니다.
해결책
첫 번째 인수는 객체 참조 (또는 null
정적 방법의 경우); 거기에 마술이 없습니다.
re 초 그러나 인수 - 그것은 관리되지 않는 포인터 (기본 INT)입니다. 요컨대, 대안은 없습니다 직접 이 생성자를 사용할 수있는 C# syntax- 특정 IL 명령을 사용합니다 (ldftn
) 메타 데이터에서 기능을 해결합니다. 그러나 사용할 수 있습니다 Delegate.CreateDelegate
반사를 통해 대의원을 만듭니다. IL Emit을 사용할 수도 있습니다 (DynamicMethod
등), 그러나 재미 있지 않습니다.
다른 팁
먼저 대의원을 정의합니다 (이것은 Visual Studio가 대상 방법의 서명을 아는 방법입니다).
delegate void MyDelegate();
그런 다음 다음과 같은 대의원 인스턴스를 구성합니다.
MyDelegate method = new MyDelegate({method name});
// If this was the method you wanted to invoke:
void MethodToInvoke()
{
// do something
}
MyDelegate method = new MyDelegate(MethodToInvoke);
C#은 대의원의 서명과 일치하는 메소드를 자동으로 선택합니다.
편집 : Visual Studio의 Intellisense가 당신에게 int () target
제안, 그것은 당신이 사용할 수있는 c# 메소드의 서명을 보여줍니다. C# 컴파일러는 C# 표현을 IL로 변환합니다. IL은 C 스타일 언어가 아니기 때문에 IL 구현은 다르게 보일 것입니다. C# 컴파일러는 구현 세부 사항을 추상화하기 위해 구문 설탕을 제공합니다.
이것은 단지 추측 일이므로, 내가 틀렸다면 나를 쏘지 마십시오. 그러나 나는 Intellisense가 Invoke
대의원에 정의 된 메소드. 반사기는 명확하게 보여줍니다 Invoke
메소드 켜짐 System.Action<T>
이다:
[MethodImpl(0, MethodCodeType=MethodCodeType.Runtime)]
public virtual void Invoke(T obj);
Intellisense가 제공하는 서명 제안과 동일합니다. 마법은 지능적이며 대의원 유형을 발견 할 때 Invoke
방법과 일치하는 대상을 취하는 생성자를 제안합니다.