Quellcodegeneratoren (Source Generators) hat Microsoft bereits in .NET 5.0 und C# 9.0 eingeführt. Nun gibt es in .NET 7.0 einen solchen Generator für reguläre Ausdrücke in der Klasse System.Text.RegularExpressions.Generator
, der die Ausführung von regulären Ausdrücken gegenüber der bisherige Laufzeitinterpretierung oder Laufzeitkompilierung (RegexOptions.Compiled
) der regulären Ausdrücke beschleunigt. Außerdem ist die Codegenerierung zur Entwicklungszeit kompatibel mit der in .NET aufkommenden Ahead-of-Time-Kompilierung (siehe Teil 17 dieser Serie), die kein Kompilieren zur Laufzeit mehr zulässt.
Anzeige
Dr. Holger Schwichtenberg ist Chief Technology Expert bei MAXIMAGO, die Innovations- und Experience-getriebener Softwareentwicklung, u.a. in hochkritischen sicherheitstechnischen Bereichen, anbietet. Zudem ist er Leiter des Expertennetzwerks www.IT-Visions.de, das mit 38 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratung und Schulung bei der Entwicklung sowie dem Betrieb von Software unterstützt.
Dazu schreibt man eine partielle Klasse mit einer partiellen Methode (siehe Listing). Diese Methode annotiert man mit System.Text.RegularExpressions.GeneratedRegexAttribute
(in der Preview-Phase wurde noch der Klassenname RegexGenerator verwendet
) unter Angabe des regulären Ausdrucks und gegebenenfalls erforderlicher Optionen für den RegEx-Parser.
Beispiel
Bisher arbeitete man mit regulären Ausdrücken in .NET mit der Klasse System.Text.RegularExpressions.RegEx
unter Angabe des regulären Ausdrucks im Konstruktor. Der reguläre Ausdruck wurde dabei entweder zur Laufzeit interpretiert
public string ExtractEMail_Classic(string input)
{
var re =
new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
var m = re.Match(input);
return m.Value;
}
oder zur Laufzeit in Intermediate Language kompiliert:
Anzeige
public string ExtractEMail_ClassicCompiled(string input)
{
// Specifies that the regular expression is compiled to MSIL code,
// instead of being interpreted. Compiled regular expressions
// maximize run-time performance at the expense of initialization time.
var re =
new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
RegexOptions.Compiled);
var m = re.Match(input);
return m.Value;
}
Neu in .NET 7.0 ist dieser Weg: Man schreibt man eine partielle Methode in einer partiellen Klasse mit der Annotation [GeneratedRegex]
:
public partial class Checker // Partielle Klasse
{
[GeneratedRegex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")]
// Partielle Methode, die dann von SG implementiert wird
public partial Regex EMailRegEx();
}
Generierte Implementierung für die partielle Methode EMailRegEx() (Abb. 1)
Diese Methode kann man dann im eigenen Code aufrufen:
public bool IsEMail(string input)
{
return EMailRegEx().IsMatch(input);
}
oder
public string ExtractEMail(string input)
{
return EMailRegEx().Match(input).Value;
}
Refactoring in Visual Studio
Visual Studio 2022 ab Version 17.4 bietet für bestehenden RegEx-Instanziierungen ein Refactoring in den neuen Source-Generator an:
Refactoring von new RegEx() in [GeneratedRegex] (Abb. 2)
Ausblick
Im nächsten Teil dieser Serie geht es um die Ausführungsgeschwindigkeit von regulären Ausdrücken mit Source-Generator im Vergleich zur Verwendung der Klasse RegEx
.
(rme)