Встроенные API, помеченные как RequiresDynamicCode
При обычных обстоятельствах вызов API-интерфейсов, аннотированных с RequiresDynamicCodeAttribute помощью приложения, опубликованного с помощью собственного AOT, активирует предупреждение IL3050 (избегайте вызова элементов, аннотированных с помощью "RequiresDynamicCodeAttribute" при публикации в качестве собственного AOT). API- интерфейсы, которые активируют предупреждение, могут неправильно вести себя после компиляции AOT.
Некоторые API-интерфейсы с аннотированием RequiresDynamicCode по-прежнему можно использовать без активации предупреждения при вызове в определенном шаблоне. При использовании в рамках шаблона вызов API может быть статически проанализирован компилятором, не создает предупреждение и ведет себя должным образом во время выполнения.
Метод Enum.GetValues(Type)
Вызовы этого API не вызывают предупреждение, если конкретный тип перечисления статически отображается в тексте вызывающего метода. Например, Enum.GetValues(typeof(AttributeTargets))
не активирует предупреждение, но Enum.GetValues(typeof(T))
и Enum.GetValues(someType)
делает это.
Метод Marshal.DestroyStructure(IntPtr, Type)
Вызовы этого API не вызывают предупреждение, если конкретный тип статически отображается в тексте вызывающего метода. Например, Marshal.DestroyStructure(offs, typeof(bool))
не активирует предупреждение, но Marshal.DestroyStructure(offs, typeof(T))
и Marshal.DestroyStructure(offs, someType)
делает это.
Метод Marshal.GetDelegateForFunctionPointer(IntPtr, Type)
Вызовы этого API не вызывают предупреждение, если конкретный тип статически отображается в тексте вызывающего метода. Например, Marshal.GetDelegateForFunctionPointer(ptr, typeof(bool))
не активирует предупреждение, но Marshal.GetDelegateForFunctionPointer(ptr, typeof(T))
и Marshal.GetDelegateForFunctionPointer(ptr, someType)
делает это.
Метод Marshal.OffsetOf(Type, String)
Вызовы этого API не вызывают предупреждение, если конкретный тип статически отображается в тексте вызывающего метода. Например, Marshal.OffsetOf(typeof(Point), someField)
не активирует предупреждение, но Marshal.OffsetOf(typeof(T), someField)
и Marshal.OffsetOf(someType, someField)
делает это.
Метод Marshal.PtrToStructure(IntPtr, Type)
Вызовы этого API не вызывают предупреждение, если конкретный тип статически отображается в тексте вызывающего метода. Например, Marshal.PtrToStructure(offs, typeof(bool))
не активирует предупреждение, но Marshal.PtrToStructure(offs, typeof(T))
и Marshal.PtrToStructure(offs, someType)
делает это.
Метод Marshal.SizeOf(Type)
Вызовы этого API не вызывают предупреждение, если конкретный тип статически отображается в тексте вызывающего метода. Например, Marshal.SizeOf(typeof(bool))
не активирует предупреждение, но Marshal.SizeOf(typeof(T))
и Marshal.SizeOf(someType)
делает это.
Метод MethodInfo.MakeGenericMethod(Type[]) (.NET 9+)
Вызовы этого API не вызывают предупреждение, если определение универсального метода и аргументы экземпляра статически видны в тексте вызывающего метода. Например, typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(typeof(int))
. В качестве аргумента также можно использовать универсальный параметр: typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(typeof(T))
также не предупреждает.
Если определение универсального типа статически отображается в тексте вызывающего метода, а все универсальные параметры этого типа ограничены классом, вызов также не активирует предупреждение IL3050. В этом случае аргументы не должны быть статически видимыми. Например:
// No IL3050 warning on MakeGenericMethod because T is constrained to be class
typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(Type.GetType(Console.ReadLine()));
class SomeType
{
public void GenericMethod<T>() where T : class { }
}
Все остальные случаи, такие как someMethod.MakeGenericMethod(typeof(int))
или typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(someType)
где someType
имеет неизвестное значение, активируют предупреждение.
Метод Type.MakeGenericType(Type[]) (.NET 9+)
Вызовы этого API не активируют предупреждение, если определение универсального типа и аргументы экземпляра статически видны в тексте вызывающего метода. Например, typeof(List<>).MakeGenericType(typeof(int))
. В качестве аргумента также можно использовать универсальный параметр: typeof(List<>).MakeGenericType(typeof(T))
также не предупреждает.
Если определение универсального типа статически отображается в тексте вызывающего метода, а все универсальные параметры этого типа ограничены классом, вызов также не активирует предупреждение IL3050. В этом случае аргументы не должны быть статически видимыми. Например:
// No IL3050 warning on MakeGenericType because T is constrained to be class
typeof(Generic<>).MakeGenericType(Type.GetType(Console.ReadLine()));
class Generic<T> where T : class { }
Все остальные случаи, такие как someType.MakeGenericType(typeof(int))
или typeof(List<>).MakeGenericType(someType)
где someType
имеет неизвестное значение, активируют предупреждение.