Прочитать на английском

Поделиться через


Встроенные API, помеченные Как ТребуетСяUnreferencedCode

При обычных обстоятельствах вызов API-интерфейсов, аннотированных с помощью приложения, опубликованного с RequiresUnreferencedCodeAttribute обрезкой триггеров, предупреждает IL2026 (члены, атрибуты с атрибутами RequiresUnreferencedCode могут прервать при обрезке). API- интерфейсы, которые активируют предупреждение, могут неправильно вести себя в обрезаном развертывании.

Некоторые API-интерфейсы, аннотированные [RequiresUnreferencedCode] , по-прежнему можно использовать без активации предупреждения, если они вызываются в определенном шаблоне. При использовании в рамках шаблона вызов API может быть статически проанализирован компилятором, не создает предупреждение и ведет себя должным образом во время выполнения.

Метод MethodInfo.MakeGenericMethod(Type[])

Вызовы этого API не вызывают предупреждение, если определение универсального метода статически видно в теле вызывающего метода, и ни один из универсальных параметров универсального метода не имеет new() ограничения или DynamicallyAccessedMembers атрибута. Например, не создает предупреждение, typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(someType) если new() нет ограничений или DynamicallyAccessedMembers заметок для универсальных параметров.

Если универсальный метод имеет параметры с new() ограничением или DynamicallyAccessedMembers атрибутом, универсальные аргументы, используемые с MakeGenericMethod необходимостью, также должны быть статически видимы в тексте вызывающего метода. В противном случае выдается предупреждение.

Метод MethodInfo.MakeGenericType(Type[])

Вызовы этого API не активируют предупреждение, если определение универсального типа статически видно в тексте вызывающего метода, и ни один из универсальных параметров универсального типа не имеет new() ограничения или DynamicallyAccessedMembers атрибута. Например, не создает предупреждение, typeof(SomeType<>).MakeGenericType(someType) если new() нет ограничений или DynamicallyAccessedMembers заметок для универсальных параметров.

Если универсальный тип имеет параметры с new() ограничением или DynamicallyAccessedMembers атрибутом, универсальные аргументы, используемые с MakeGenericType необходимостью, также должны быть статически видимы в тексте вызывающего метода. В противном случае выдается предупреждение.

Метод RuntimeHelpers.RunClassConstructor(Type)

Вызовы этого API не вызывают предупреждение, если конкретный тип статически отображается в тексте вызывающего метода. Например, RuntimeHelpers.RunClassConstructor(typeof(string).TypeHandle) не активирует предупреждение, но RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle) и RuntimeHelpers.RunClassConstructor(someTypeHandle) делает это.

Кроме того, начиная с .NET 9 предупреждение не выдается при загрузке дескриптора типа из Type сохраненного в расположении, аннотированного как DynamicallyAccessedMemberTypes.NonPublicConstructors. Это связано с тем, что недоступные конструкторы включают статический конструктор:

C#
static void M<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>
    ([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type t)
{
    RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // No IL2026 warning
    RuntimeHelpers.RunClassConstructor(t.TypeHandle); // No IL2026 warning
}

Перегрузки Type.GetType

Вызовы этого API не активируют предупреждение, если строковый параметр передается в виде строкового литерала и нечувствительного поиска регистра не запрашивается. API также не активирует предупреждение, если используется не литеральная строка, но строка была загружена из расположения, аннотированного с [DynamicallyAccessedMembers].

C#
static void GetTheType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] string s)
{
    Type.GetType(s); // No IL2026 warning
}