Inicializadores de módulosModule Initializers
- [x] propuesto[x] Proposed
- [] Prototipo: en curso[ ] Prototype: In Progress
- [] Implementación: en curso[ ] Implementation: In Progress
- [] Especificación: no iniciada[ ] Specification: Not Started
ResumenSummary
Aunque la plataforma .NET tiene una característica que admite directamente la escritura de código de inicialización para el ensamblado (técnicamente, el módulo), no se expone en C#.Although the .NET platform has a feature that directly supports writing initialization code for the assembly (technically, the module), it is not exposed in C#. Se trata de un escenario bastante nicho, pero una vez que se encuentra en él, las soluciones parecen ser bastante complicadas.This is a rather niche scenario, but once you run into it the solutions appear to be pretty painful. Hay informes de varios clientes (dentro y fuera de Microsoft) que luchan con el problema y no hay ningún caso más sin documentar.There are reports of a number of customers (inside and outside Microsoft) struggling with the problem, and there are no doubt more undocumented cases.
MotivaciónMotivation
- Permite que las bibliotecas realicen una inicialización diligente y única cuando se cargan, con una sobrecarga mínima y sin que el usuario tenga que llamar explícitamente a nada.Enable libraries to do eager, one-time initialization when loaded, with minimal overhead and without the user needing to explicitly call anything
- Un punto de dolor determinado de
static
los enfoques del constructor actual es que el tiempo de ejecución debe realizar comprobaciones adicionales sobre el uso de un tipo con un constructor estático, para decidir si el constructor estático debe ejecutarse o no.One particular pain point of currentstatic
constructor approaches is that the runtime must do additional checks on usage of a type with a static constructor, in order to decide whether the static constructor needs to be run or not. Esto agrega una sobrecarga mensurable.This adds measurable overhead. - Habilitar generadores de código fuente para ejecutar una lógica de inicialización global sin que el usuario tenga que llamar explícitamente a nadaEnable source generators to run some global initialization logic without the user needing to explicitly call anything
Diseño detalladoDetailed design
Un método se puede designar como inicializador de módulo al decorarlo con un [ModuleInitializer]
atributo.A method can be designated as a module initializer by decorating it with a [ModuleInitializer]
attribute.
using System;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
El atributo se puede usar de la siguiente manera:The attribute can be used like this:
using System.Runtime.CompilerServices;
class C
{
[ModuleInitializer]
internal static void M1()
{
// ...
}
}
Algunos requisitos se imponen en el método de destino de este atributo:Some requirements are imposed on the method targeted with this attribute:
- El método debe ser
static
.The method must bestatic
. - El método no debe tener parámetros.The method must be parameterless.
- El método debe devolver
void
.The method must returnvoid
. - El método no debe ser genérico ni estar incluido en un tipo genérico.The method must not be generic or be contained in a generic type.
- El método debe ser accesible desde el módulo contenedor.The method must be accessible from the containing module.
- Esto significa que la accesibilidad efectiva del método debe ser
internal
opublic
.This means the method's effective accessibility must beinternal
orpublic
. - Esto también significa que el método no puede ser una función local.This also means the method cannot be a local function.
- Esto significa que la accesibilidad efectiva del método debe ser
Cuando se encuentran uno o más métodos válidos con este atributo en una compilación, el compilador emitirá un inicializador de módulo que llama a cada uno de los métodos con atributos.When one or more valid methods with this attribute are found in a compilation, the compiler will emit a module initializer which calls each of the attributed methods. Las llamadas se emitirán en un orden reservado pero determinista.The calls will be emitted in a reserved, but deterministic order.
InconvenientesDrawbacks
¿Por qué no se debe hacer esto?Why should we not do this?
- Es posible que las herramientas de terceros existentes para los inicializadores de módulos de "inserción" sean suficientes para los usuarios que han solicitado esta característica.Perhaps the existing third-party tooling for "injecting" module initializers is sufficient for users who have been asking for this feature.