문제

일반적으로 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 방법과 일치하는 대상을 취하는 생성자를 제안합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top