|
| 1 | +--- |
| 2 | +title: Intrinsic APIs marked RequiresUnreferencedCode |
| 3 | +description: Learn how the tooling recognizes certain patterns in calls to APIs annotated with RequiresUnreferencedCode. |
| 4 | +author: MichalStrehovsky |
| 5 | +ms.author: michals |
| 6 | +ms.date: 09/13/2024 |
| 7 | +--- |
| 8 | + |
| 9 | +# Intrinsic APIs marked RequiresUnreferencedCode |
| 10 | + |
| 11 | +Under normal circumstances, calling APIs annotated with <xref:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute> in an app published with trimming triggers warning [IL2026 (Members attributed with RequiresUnreferencedCode may break when trimming)](trim-warnings/il2026.md). APIs that trigger the warning might not behave correctly in a trimmed deployment. |
| 12 | + |
| 13 | +Some APIs annotated `[RequiresUnreferencedCode]` can still be used without triggering the warning if they're called in a specific pattern. When used as part of a pattern, the call to the API can be statically analyzed by the compiler, does not generate a warning, and behaves as expected at run time. |
| 14 | + |
| 15 | +## MethodInfo.MakeGenericMethod(Type[]) method |
| 16 | + |
| 17 | +Calls to this API don't trigger a warning if the generic method definition is statically visible within the calling method body and none of the generic method's generic parameters have the `new()` constraint or `DynamicallyAccessedMembers` attribute. For example, `typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(someType)` doesn't generate a warning provided there are no `new()` constraints or `DynamicallyAccessedMembers` annotations on the generic parameters. |
| 18 | + |
| 19 | +If the generic method has parameters with the `new()` constraint or `DynamicallyAccessedMembers` attribute, the generic arguments used with `MakeGenericMethod` need to also be statically visible within the calling method body. Otherwise the warning is issued. |
| 20 | + |
| 21 | +## MethodInfo.MakeGenericType(Type[]) method |
| 22 | + |
| 23 | +Calls to this API don't trigger a warning if the generic type definition is statically visible within the calling method body and none of the generic type's generic parameters have the `new()` constraint or `DynamicallyAccessedMembers` attribute. For example, `typeof(SomeType<>).MakeGenericType(someType)` doesn't generate a warning provided there are no `new()` constraints or `DynamicallyAccessedMembers` annotations on the generic parameters. |
| 24 | + |
| 25 | +If the generic type has parameters with the `new()` constraint or `DynamicallyAccessedMembers` attribute, the generic arguments used with `MakeGenericType` need to also be statically visible within the calling method body. Otherwise the warning is issued. |
| 26 | + |
| 27 | +## RuntimeHelpers.RunClassConstructor(Type) method |
| 28 | + |
| 29 | +Calls to this API don't trigger a warning if the concrete type is statically visible in the calling method body. For example, `RuntimeHelpers.RunClassConstructor(typeof(string).TypeHandle)` does not trigger a warning, but `RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle)` and `RuntimeHelpers.RunClassConstructor(someTypeHandle)` do. |
| 30 | + |
| 31 | +Additionally, starting with .NET 9, the warning isn't issued when the type handle was loaded from `Type` stored in a location annotated as `DynamicallyAccessedMemberTypes.NonPublicConstructors`. That's because non-public constructors include the static constructor: |
| 32 | + |
| 33 | +```csharp |
| 34 | +static void M<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T> |
| 35 | + ([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t) |
| 36 | +{ |
| 37 | + RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // No IL2026 warning |
| 38 | + RuntimeHelpers.RunClassConstructor(t.TypeHandle); // No IL2026 warning |
| 39 | +} |
| 40 | + |
| 41 | +``` |
| 42 | + |
| 43 | +## Type.GetType overloads |
| 44 | + |
| 45 | +Calls to this API don't trigger a warning if the string parameter is passed as a string literal and case-insensitive search isn't requested. The API also doesn't trigger a warning if a non-literal string is used, but the string was loaded from a location annotated with `[DynamicallyAccessedMembers]`. |
| 46 | + |
| 47 | +```csharp |
| 48 | +static void GetTheType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] string s) |
| 49 | +{ |
| 50 | + Type.GetType(s); // No IL2026 warning |
| 51 | +} |
| 52 | +``` |
0 commit comments