__DynamicallyInvokable 속성은 무엇입니까?


181

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

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


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

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

1
그리고 System.ServiceModel v3BasicHttpBinding.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.InvocableAttributeCtorTokenIsNonW8PFrameworkAPI()메소드에 의해 호출됩니다 .
Mark Hurd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.