标记为 RequiresDynamicCode 的内部 API

在正常情况下,在使用本机 AOT 发布的应用中调用使用 RequiresDynamicCodeAttribute 进行批注的 API 时,会触发警告 IL3050(避免在发布为本机 AOT 时调用使用“RequiresDynamicCodeAttribute”进行批注的成员)。 触发警告的 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 具有未知值)都会触发警告。