在正常情况下,在使用本机 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
具有未知值)都会触发警告。