Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Notatka
Ten artykuł jest specyfikacją funkcji. Specyfikacja służy jako dokument projektowy dla funkcji. Zawiera proponowane zmiany specyfikacji wraz z informacjami wymaganymi podczas projektowania i opracowywania funkcji. Te artykuły są publikowane do momentu sfinalizowania proponowanych zmian specyfikacji i włączenia ich do obecnej specyfikacji ECMA.
Mogą wystąpić pewne rozbieżności między specyfikacją funkcji a ukończoną implementacją. Te różnice są ujęte w odpowiednich notatkach ze spotkań projektowania języka (LDM) .
Więcej informacji na temat procesu wdrażania specyfikacji funkcji można znaleźć w standardzie języka C# w artykule dotyczącym specyfikacji .
Problem z mistrzem: https://github.com/dotnet/csharplang/issues/2608
Streszczenie
Mimo że platforma .NET ma funkcję , która bezpośrednio obsługuje pisanie kodu inicjowania dla zestawu (technicznie, modułu), nie jest uwidoczniona w języku C#. Jest to raczej niszowy scenariusz, ale kiedy się z nim zetkniesz, rozwiązania mogą okazać się dość bolesne. Istnieją raporty o pewnej liczbie klientów (zarówno wewnątrz, jak i poza firmą Microsoft), którzy zmagają się z problemem, a nie ma wątpliwości, że istnieje więcej nieudokumentowanych przypadków.
Motywacja
- Umożliwiaj bibliotekom szybkie inicjowanie jednorazowe podczas ładowania z minimalnym obciążeniem i bez konieczności jawnego wywoływania niczego przez użytkownika
- Jednym z problematycznych aspektów obecnego podejścia do konstruktora
staticjest to, że środowisko uruchomieniowe musi przeprowadzić dodatkowe kontrole użycia typu z konstruktorem statycznym, aby ustalić, czy należy uruchomić konstruktor statyczny. Zwiększa to wymierne obciążenie. - Włącz generatory źródeł, aby uruchamiać pewną globalną logikę inicjowania bez konieczności jawnego wywoływania niczego przez użytkownika
Szczegółowy projekt
Metodę można wyznaczyć jako inicjator modułu, dekorując ją za pomocą atrybutu [ModuleInitializer].
using System;
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ModuleInitializerAttribute : Attribute { }
}
Atrybut można użyć w następujący sposób:
using System.Runtime.CompilerServices;
class C
{
[ModuleInitializer]
internal static void M1()
{
// ...
}
}
Niektóre wymagania są nakładane na metodę docelową tego atrybutu:
- Metoda musi być
static. - Metoda musi być bez parametrów.
- Metoda musi zwrócić
void. - Metoda nie może być ogólna ani nie może być zawarta w typie ogólnym.
- Metoda musi być dostępna z modułu zawierającego.
- Oznacza to, że efektywna dostępność metody musi być
internallubpublic. - Oznacza to również, że metoda nie może być funkcją lokalną.
- Oznacza to, że efektywna dostępność metody musi być
Gdy w kompilacji znajduje się co najmniej jedna prawidłowa metoda z tym atrybutem, kompilator emituje inicjator modułu, który wywołuje każdą z metod przypisanych. Wywołania będą emitowane w zarezerwowanej kolejności, ale deterministycznej.
Niedogodności
Dlaczego tego nie zrobić?
- Być może istniejące narzędzia innych firm do „wstrzykiwania” inicjatorów modułów są wystarczające dla użytkowników, którzy prosili o tę funkcję.
Spotkania projektowe
8 kwietnia 2020 r.
C# feature specifications