API intrínsecas marcadas con RequireDynamicCode
En circunstancias normales, llamar a API anotadas con RequiresDynamicCodeAttribute en una aplicación publicada con activadores AOT nativos generan la advertencia IL3050 (evite llamar a miembros anotados con "RequireDynamicCodeAttribute" al publicar como AOT nativo). Es posible que las API que generen la advertencia no respondan correctamente después de la compilación AOT.
Algunas API anotadas con RequiresDynamicCode todavía se pueden usar sin generar la advertencia cuando se llama con un patrón específico. Cuando se usa como parte de un patrón, el compilador puede analizar estáticamente la llamada a la API, no genera una advertencia y funciona según lo esperado en tiempo de ejecución.
Método Enum.GetValues(Type)
Las llamadas a esta API no generan una advertencia si el tipo de enumeración concreta es visible estáticamente en el cuerpo del método de la llamada. Por ejemplo, Enum.GetValues(typeof(AttributeTargets))
no genera ninguna advertencia, pero sí lo hace Enum.GetValues(typeof(T))
y Enum.GetValues(someType)
.
Método Marshal.DestroyStructure(IntPtr, Type)
Las llamadas a esta API no generan una advertencia si el tipo concreto es visible estáticamente en el cuerpo del método de la llamada. Por ejemplo, Marshal.DestroyStructure(offs, typeof(bool))
no genera ninguna advertencia, pero sí lo hace Marshal.DestroyStructure(offs, typeof(T))
y Marshal.DestroyStructure(offs, someType)
.
Método Marshal.GetDelegateForFunctionPointer(IntPtr, Type)
Las llamadas a esta API no generan una advertencia si el tipo concreto es visible estáticamente en el cuerpo del método de la llamada. Por ejemplo, Marshal.GetDelegateForFunctionPointer(ptr, typeof(bool))
no genera ninguna advertencia, pero sí lo hace Marshal.GetDelegateForFunctionPointer(ptr, typeof(T))
y Marshal.GetDelegateForFunctionPointer(ptr, someType)
.
Método Marshal.OffsetOf(Type, String)
Las llamadas a esta API no generan una advertencia si el tipo concreto es visible estáticamente en el cuerpo del método de la llamada. Por ejemplo, Marshal.OffsetOf(typeof(Point), someField)
no genera ninguna advertencia, pero sí lo hace Marshal.OffsetOf(typeof(T), someField)
y Marshal.OffsetOf(someType, someField)
.
Método Marshal.PtrToStructure(IntPtr, Type)
Las llamadas a esta API no generan una advertencia si el tipo concreto es visible estáticamente en el cuerpo del método de la llamada. Por ejemplo, Marshal.PtrToStructure(offs, typeof(bool))
no genera ninguna advertencia, pero sí lo hace Marshal.PtrToStructure(offs, typeof(T))
y Marshal.PtrToStructure(offs, someType)
.
Método Marshal.SizeOf(Type)
Las llamadas a esta API no generan una advertencia si el tipo concreto es visible estáticamente en el cuerpo del método de la llamada. Por ejemplo, Marshal.SizeOf(typeof(bool))
no genera ninguna advertencia, pero sí lo hace Marshal.SizeOf(typeof(T))
y Marshal.SizeOf(someType)
.
Método MethodInfo.MakeGenericMethod(Type[]) (.NET 9+)
Las llamadas a esta API no generan una advertencia si tanto la definición genérica del método como los argumentos de creación de instancias son visibles estáticamente dentro del cuerpo del método de la llamada. Por ejemplo, typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(typeof(int))
. También es posible usar un parámetro genérico como argumento: typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(typeof(T))
tampoco genera una advertencia.
Si la definición de tipo genérico es visible estáticamente dentro del cuerpo del método de la llamada y todos los parámetros genéricos de esta están limitados para ser una clase, la llamada tampoco genera la advertencia IL3050. En este caso, los argumentos no tienen que ser visibles estáticamente. Por ejemplo:
// 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 { }
}
En todos los demás casos, como someMethod.MakeGenericMethod(typeof(int))
o typeof(SomeType).GetMethod("GenericMethod").MakeGenericMethod(someType)
donde someType
tiene un valor desconocido, se genera una advertencia.
Método Type.MakeGenericType(Type[]) (.NET 9+)
Las llamadas a esta API no generan una advertencia si tanto la definición de tipo genérica como los argumentos de creación de instancias son visibles estáticamente dentro del cuerpo del método de la llamada. Por ejemplo, typeof(List<>).MakeGenericType(typeof(int))
. También es posible usar un parámetro genérico como argumento: typeof(List<>).MakeGenericType(typeof(T))
tampoco genera una advertencia.
Si la definición de tipo genérico es visible estáticamente dentro del cuerpo del método de la llamada y todos los parámetros genéricos de esta están limitados para ser una clase, la llamada tampoco genera la advertencia IL3050. En este caso, los argumentos no tienen que ser visibles estáticamente. Por ejemplo:
// 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 { }
En todos los demás casos, como someType.MakeGenericType(typeof(int))
o typeof(List<>).MakeGenericType(someType)
donde someType
tiene un valor desconocido, se genera una advertencia.