Bedingte Zeichenfolgenauswertung in Debugmethoden
Interpolierte Zeichenfolgen werden häufig als Assert-Meldungen verwendet, zum Beispiel:
Debug.Assert(result != x, $"Unexpected result {result}");
In früheren Versionen führt dies jedoch dazu, dass eine Zeichenfolge für die Meldung einschließlich des Formatierungsergebnis erstellt wird, auch wenn die Bedingung true
ist. De typische Verwendung für Assertionen ist, dass sie von einer Bedingung handeln, die immer wahr sein sollte.
C# 10 bietet Unterstützung für eine bessere Zeichenfolgeninterpolation, einschließlich der Möglichkeit, neben Zeichenfolgen auch benutzerdefinierte „Handler“ als Ziel zu verwenden. In .NET 6 verfügt die Klasse Debug über neue Überladungen von Assert, WriteIf und WriteLineIf, die diese Funktion verwenden, um die Formatierungselemente der interpolierten Zeichenfolge bedingt auszuwerten, wenn die Nachricht erforderlich ist. Der C#-Compiler bevorzugt diese neuen Überladungen. Wenn die Formatierungselemente den Zustand mutieren und das Programm darauf angewiesen war, dass diese Mutationen sichtbar sind, auch wenn die Assertion nicht ausgelöst wurde, könnten Sie einen Unterschied im Verhalten feststellen.
Vorheriges Verhalten
Im folgenden Code wird immer r.ToString()
aufgerufen.
Debug.Assert(true, $"{r.ToString()}");
Neues Verhalten
Im folgende Code wird r.ToString()
nie aufgerufen, da die Meldung nur benötigt wird, wenn die Bedingung false
ist.
Debug.Assert(true, $"{r.ToString()}");
Eingeführt in Version
6.0 RC 1
Typ des Breaking Changes
Diese Änderung kann sich auf die Quellkompatibilität auswirken.
Grund für die Änderung
Diese Änderung wurde eingeführt, um die Leistung zu verbessern.
Empfohlene Maßnahme
Interpolierte Zeichenfolgen, die mit Debug-Methoden verwendet werden, sollten den freigegebenen Zustand nicht mutieren. (Diese Methoden sind auch von der DEBUG
-Kompilierungskonstante bedingt.) Wenn es aus irgendeinem Grund wichtig ist, das alte Verhalten beizubehalten, fügen Sie eine (string)
-Umwandlung vor der interpolierten Zeichenfolge hinzu. Diese Umwandlung zwingt den Compiler, die vorhandene Überladung zu binden und sicherzustellen, dass die Zeichenfolge immer materialisiert wird.
Betroffene APIs
- System.Diagnostics.Debug.Assert(Boolean, String)
- System.Diagnostics.Debug.Assert(Boolean, String, String)
- System.Diagnostics.Debug.Assert(Boolean, String, String, Object[])
- System.Diagnostics.Debug.WriteIf(Boolean, String)
- System.Diagnostics.Debug.WriteIf(Boolean, String, String)
- System.Diagnostics.Debug.WriteIf(Boolean, Object, String)
- System.Diagnostics.Debug.WriteLineIf(Boolean, String)
- System.Diagnostics.Debug.WriteLineIf(Boolean, String, String)
- System.Diagnostics.Debug.WriteLineIf(Boolean, Object, String)