__DynamicallyInvokable 속성은 무엇입니까?


181

을 통해 찾고 System.Linq.EnumerableDotPeek I 통지에 몇 가지 방법은 맛되는 [__DynamicallyInvokable]속성.

이 속성은 어떤 역할을합니까? DotPeek에 의해 추가 된 것이거나 다른 역할을 수행하여 컴파일러에게 방법을 최적화하는 가장 좋은 방법을 알려주는 것일까 요?


2
String.Empty에도 btw가 있습니다.
— Marc Gravell

1
그렇습니다 IReadOnlyCollection<T>.
— Drew Noakes

1
그리고 System.ServiceModel v3의 BasicHttpBinding.TextEncoding(새로운 기본 클래스까지 이동되고있다 V4에있는 HttpBindingBase.TextEncoding)
— 루벤 Bartelink에게

또한 DayOfWeek와 같은 시스템 열거 형의 정수 값에도 사용됩니다.
— beauXjames

나는 경우가 있으면이 속성 방법 (DateTime.AddYears 닷넷 4.5)에서 발생 조립체 인라인 때
— gdbdable

답변:


139

문서화되어 있지 않지만 .NET 4.5의 최적화 중 하나처럼 보입니다. 리플렉션 유형 정보 캐시를 프라이밍하는 데 사용되어 일반적인 프레임 워크 유형의 후속 리플렉션 코드가 더 빠르게 실행됩니다. System.Reflection.Assembly.cs, RuntimeAssembly.Flags 속성에 대한 참조 소스에 이에 대한 설명이 있습니다.

 // Each blessed API will be annotated with a "__DynamicallyInvokableAttribute".
 // This "__DynamicallyInvokableAttribute" is a type defined in its own assembly.
 // So the ctor is always a MethodDef and the type a TypeDef.
 // We cache this ctor MethodDef token for faster custom attribute lookup.
 // If this attribute type doesn't exist in the assembly, it means the assembly
 // doesn't contain any blessed APIs.
 Type invocableAttribute = GetType("__DynamicallyInvokableAttribute", false);
 if (invocableAttribute != null)
 {
     Contract.Assert(((MetadataToken)invocableAttribute.MetadataToken).IsTypeDef);

     ConstructorInfo ctor = invocableAttribute.GetConstructor(Type.EmptyTypes);
     Contract.Assert(ctor != null);

     int token = ctor.MetadataToken;
     Contract.Assert(((MetadataToken)token).IsMethodDef);

     flags |= (ASSEMBLY_FLAGS)token & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK;
 }

더 많은 힌트가 없다면 "축복 된 API"가 무엇을 의미 할 수 있습니다. 컨텍스트에서 이것은 프레임 워크 자체의 유형에서만 작동한다는 것이 분명합니다. 어딘가에 유형과 메소드에 적용된 속성을 확인하는 추가 코드가 있어야합니다. 그것이 어디에 있는지는 모르지만 캐싱을 위해 모든 .NET 유형을 볼 필요가 있다는 점을 감안할 때 Ngen.exe 만 생각할 수 있습니다.


7
저장된 값을 사용하여 WP8에서 API를 사용할 수 있는지 확인하는 것 같습니다.
— usr

1
+1 OP의 Q에 대한 나의 의견을 참조하십시오-CLR이이를 기반으로 까다로운 것처럼 보이는 사례는 통일 하에서 (예를 들어, 새로운 기본 클래스로 한 단계 아래로) 약간의 이동을 처리하는 것입니다
— Ruben Bartelink

2
그것이 완전히 다른 [TypeForwardTo] 트릭입니다.
— 한스 Passant

@HansPassant Interesting-내가 잘못한 것처럼 들리므로 원래 어셈블리 / 유형을 조사 할 생각이 없었습니다. 결론은 4.5에서 인용 된 속성 (유형이 아님)이 3.5의 위치 (기술적으로는)에 대해 상대적으로 움직 였다는 것 System.ServiceModel 3.0입니다. 나는 통일 라 가정했다 mscorlib참조 놀이했지만 많은 일부 어쨌든 할 내 특정 문제에 주위 다시 돌고 있습니다 - 다시보고 및 / 또는 인해 과정에서 내 의견에 어떤 오해의 소지가 톤을 제거합니다 ...
— 루벤 Bartelink

1
@HansPassant 추가 연구에서 ... Cant는 Type Forwarding이 Forwarding Types 이외의 일을하는 것을 보았습니다. 그래서이 시점에서 나는 완전히 다른 비트 와 다른 것을 구걸합니다 . CLR2 어셈블리를 참조 할 때 System.ServiceModel v3CLR4에서 자동 업그레이드 할 때로드하는 작업의 힘은 간단합니다 System.ServiceModel v4. 재미있는 점은 .NET 4.5가 System.ServiceModel새 기본 클래스 아래에있는 비트를 적절하게 업데이트 하고 속성을 한 수준 아래 로 이동한다는 것 입니다.
— Ruben Bartelink

23

Runtime*Info.IsNonW8PFrameworkAPI()내부 메소드 세트 에서 사용되는 것으로 나타났습니다 . 이 특성을 멤버에 배치하면 IsNonW8PFrameworkAPI ()가이를 반환 false하여 해당 멤버를 WinRT 응용 프로그램에서 사용할 수있게하고 The API '...' cannot be used on the current platform.예외를 종료합니다 .

프로파일 러 작성자는 WinRT에서 액세스하려는 경우 프로파일 러가 방출 한 멤버에이 속성을 프레임 워크 어셈블리에 배치해야합니다.


1
예, @Hans가 찾은 코드는 님이 찾은 플래그를 설정합니다.이 플래그는 언급 RuntimeAssembly.InvocableAttributeCtorToken한 IsNonW8PFrameworkAPI()메소드에 의해 호출됩니다 .
— Mark Hurd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.