Partilhar via


APIs intrínsecas marcadas como RequiresDynamicCode

Em circunstâncias normais, chamar APIs anotadas em RequiresDynamicCodeAttribute um aplicativo publicado com AOT nativo aciona o aviso IL3050 (Evite chamar membros anotados com 'RequiresDynamicCodeAttribute' ao publicar como AOT nativo). As APIs que disparam o aviso podem não se comportar corretamente após a compilação da AOT.

Algumas APIs anotadas RequiresDynamicCode ainda podem ser usadas sem acionar o aviso quando chamadas em um padrão específico. Quando usada como parte de um padrão, a chamada à API pode ser analisada estaticamente pelo compilador, não gera um aviso e comporta-se como esperado em tempo de execução.

Método Enum.GetValues(Type)

As chamadas para esta API não disparam um aviso se o tipo de enum concreto estiver estaticamente visível no corpo do método de chamada. Por exemplo, Enum.GetValues(typeof(AttributeTargets)) não aciona um aviso, mas Enum.GetValues(typeof(T)) e Enum.GetValues(someType) faz.

Método Marshal.DestroyStructure(IntPtr, Type)

As chamadas para essa API não disparam um aviso se o tipo concreto estiver visível estaticamente no corpo do método de chamada. Por exemplo, Marshal.DestroyStructure(offs, typeof(bool)) não aciona um aviso, mas Marshal.DestroyStructure(offs, typeof(T)) e Marshal.DestroyStructure(offs, someType) faz.

Método Marshal.GetDelegateForFunctionPointer(IntPtr, Type)

As chamadas para essa API não disparam um aviso se o tipo concreto estiver visível estaticamente no corpo do método de chamada. Por exemplo, Marshal.GetDelegateForFunctionPointer(ptr, typeof(bool)) não aciona um aviso, mas Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) e Marshal.GetDelegateForFunctionPointer(ptr, someType) faz.

Método Marshal.OffsetOf(Type, String)

As chamadas para essa API não disparam um aviso se o tipo concreto estiver visível estaticamente no corpo do método de chamada. Por exemplo, Marshal.OffsetOf(typeof(Point), someField) não aciona um aviso, mas Marshal.OffsetOf(typeof(T), someField) e Marshal.OffsetOf(someType, someField) faz.

Método Marshal.PtrToStructure(IntPtr, Type)

As chamadas para essa API não disparam um aviso se o tipo concreto estiver visível estaticamente no corpo do método de chamada. Por exemplo, Marshal.PtrToStructure(offs, typeof(bool)) não aciona um aviso, mas Marshal.PtrToStructure(offs, typeof(T)) e Marshal.PtrToStructure(offs, someType) faz.

Método Marshal.SizeOf(Type)

As chamadas para essa API não disparam um aviso se o tipo concreto estiver visível estaticamente no corpo do método de chamada. Por exemplo, Marshal.SizeOf(typeof(bool)) não aciona um aviso, mas Marshal.SizeOf(typeof(T)) e Marshal.SizeOf(someType) faz.

Método MethodInfo.MakeGenericMethod(Type[]) (.NET 9+)

As chamadas para essa API não disparam um aviso se a definição genérica do método e os argumentos de instanciação estiverem visíveis estaticamente no corpo do método chamador. Por exemplo, typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(typeof(int)). Também é possível usar um parâmetro genérico como argumento: typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(typeof(T)) também não avisa.

Se a definição de tipo genérica é visível estaticamente dentro do corpo do método de chamada e todos os parâmetros genéricos dele são restritos a ser uma classe, a chamada também não aciona o aviso IL3050. Neste caso, os argumentos não precisam ser visíveis estaticamente. Por exemplo:

// 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 { }
}

Todos os outros casos, como someMethod.MakeGenericMethod(typeof(int)) ou typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(someType) onde someType tem um valor desconhecido, disparam um aviso.

Método Type.MakeGenericType(Type[]) (.NET 9+)

As chamadas para essa API não disparam um aviso se a definição de tipo genérica e os argumentos de instanciação estiverem visíveis estaticamente no corpo do método de chamada. Por exemplo, typeof(List<>).MakeGenericType(typeof(int)). Também é possível usar um parâmetro genérico como argumento: typeof(List<>).MakeGenericType(typeof(T)) também não avisa.

Se a definição de tipo genérica é visível estaticamente dentro do corpo do método de chamada e todos os parâmetros genéricos dele são restritos a ser uma classe, a chamada também não aciona o aviso IL3050. Neste caso, os argumentos não precisam ser visíveis estaticamente. Por exemplo:

// 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 { }

Todos os outros casos, como someType.MakeGenericType(typeof(int)) ou typeof(List<>).MakeGenericType(someType) onde someType tem um valor desconhecido, disparam um aviso.