Evaluatie van voorwaardelijke tekenreeksen in foutopsporingsmethoden

Het is gebruikelijk om geïnterpoleerde tekenreeksen te gebruiken als assertieberichten, bijvoorbeeld:

Debug.Assert(result != x, $"Unexpected result {result}");

In eerdere versies wordt er echter een tekenreeks gemaakt voor het bericht, inclusief opmaakresultaat, bij elke aanroep, zelfs als de voorwaarde is true. En het typische gebruik voor asserties is dat ze betrekking hebben op een voorwaarde die altijd waar moet zijn.

C# 10 voegt ondersteuning toe voor betere tekenreeksinterpolatie, inclusief de mogelijkheid om aangepaste handlers te targeten naast tekenreeksen. In .NET 6 heeft de Debug-klasse nieuwe overbelastingen van Assert, WriteIf en WriteLineIf die gebruikmaken van deze functionaliteit om de geïnterpoleerde tekenreeksopmaakitems alleen voorwaardelijk te evalueren als het bericht is vereist. De C#-compiler geeft de voorkeur aan deze nieuwe overbelastingen. Als de opmaakitems een muterende toestand hadden en het programma afhankelijk was van de zichtbaarheid van die mutaties, zelfs als de bevestiging niet werd geactiveerd, kon u een verschil in gedrag constateren.

Vorig gedrag

In de volgende code wordt r.ToString() altijd aangeroepen.

Debug.Assert(true, $"{r.ToString()}");

Nieuw gedrag

In de volgende code r.ToString() wordt nooit aangeroepen, omdat het bericht alleen nodig is als de voorwaarde is false.

Debug.Assert(true, $"{r.ToString()}");

Geïntroduceerde versie

6.0 RC 1

Type van brekende verandering

Deze wijziging kan invloed hebben op broncompatibiliteit.

Reden voor wijziging

Deze wijziging is geïntroduceerd om de prestaties te verbeteren.

Geïnterpoleerde tekenreeksen die met Debug methoden worden gebruikt, mogen de gedeelde toestand niet wijzigen. (Deze methoden zijn ook afhankelijk van de DEBUG compilatieconstante.) Als het om een of andere reden essentieel is om het oude gedrag te behouden, voegt u een (string) cast toe vóór de geïnterpoleerde tekenreeks. Deze cast dwingt de compiler zich te binden aan de bestaande overload en zorgt ervoor dat de tekenreeks altijd wordt gematerialiseerd.

Betreffende API's