在正常情況下,當您在以原生 AOT 發佈的應用程式中,呼叫標註為 RequiresDynamicCodeAttribute 的 API 時,會觸發警告 IL3050 (避免在發佈為原生 AOT 時叫用標註為 ‘RequiresDynamicCodeAttribute’ 的成員)。 觸發警告的 API 在 AOT 編譯後可能無法正常運作。
某些標註為 RequiresDynamicCode 的 API 仍然可以使用,在特定模式中呼叫時不會觸發警告。 當作為模式的一部分使用時,對 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 具有未知值,會觸發警告。