Compartilhar via


APIs intrínsecas marcadas como RequiresDynamicCode

Sob as circunstâncias normais, chamar APIs anotadas com RequiresDynamicCodeAttribute em um aplicativo publicado com AOT nativo dispara 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 AOT.

Algumas APIs anotadas RequiresDynamicCode ainda podem ser usadas sem disparar 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 se comporta conforme o esperado em runtime.

Método Enum.GetValues(Type)

As chamadas para essa API não dispararão um aviso se o tipo de enumeração concreta estiver estaticamente visível no corpo do método de chamada. Por exemplo, Enum.GetValues(typeof(AttributeTargets)) não dispara um aviso, mas Enum.GetValues(typeof(T)) e Enum.GetValues(someType) sim.

Método Marshal.DestroyStructure(IntPtr, Type)

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

Método Marshal.GetDelegateForFunctionPointer(IntPtr, Type)

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

Método Marshal.OffsetOf(Type, String)

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

Método Marshal.PtrToStructure(IntPtr, Type)

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

Método Marshal.SizeOf(Type)

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

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

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

Se a definição de tipo genérico estiver estaticamente visível no corpo do método de chamada e todos os parâmetros genéricos dela forem restritos a uma classe, a chamada também não disparará o aviso IL3050. Nesse 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) em que someType tem um valor desconhecido, disparam um aviso.

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

As chamadas para essa API não dispararão um aviso se a definição do tipo genérico e os argumentos de instanciação estiverem estaticamente visíveis 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 o argumento: typeof(List<>).MakeGenericType(typeof(T)) também não avisa.

Se a definição de tipo genérico estiver estaticamente visível no corpo do método de chamada e todos os parâmetros genéricos dela forem restritos a uma classe, a chamada também não disparará o aviso IL3050. Nesse 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) em que someType tem um valor desconhecido, disparam um aviso.