Warunkowa ocena ciągu w metodach debugowania
Często używa się ciągów interpolowanych jako komunikatów asercyjnych, na przykład:
Debug.Assert(result != x, $"Unexpected result {result}");
Jednak w poprzednich wersjach powoduje to utworzenie ciągu dla komunikatu, w tym wyniku formatowania, przy każdym wywołaniu, nawet jeśli warunek to true
. Typowym zastosowaniem asercj jest to, że chodzi o warunek, który zawsze powinien być prawdziwy.
Język C# 10 dodaje obsługę lepszej interpolacji ciągów, w tym możliwość kierowania niestandardowych "procedur obsługi" oprócz ciągów. Na platformie .NET 6 Debug klasa ma nowe przeciążenia , WriteIfi WriteLineIf które wykorzystują tę funkcję do warunkowego oceniania elementów formatowania ciągów Assertinterpolowanych tylko wtedy, gdy jest wymagany komunikat. Kompilator języka C# preferuje te nowe przeciążenia. Jeśli elementy formatowania były stanem wyciszania, a program polegał na tych mutacjach, aby były widoczne, nawet jeśli twierdzenie nie wystrzeliło, można zaobserwować różnicę w zachowaniu.
Poprzednie zachowanie
W poniższym kodzie r.ToString()
zawsze będzie wywoływany.
Debug.Assert(true, $"{r.ToString()}");
Nowe zachowanie
W poniższym kodzie nigdy nie zostanie wywołany, r.ToString()
ponieważ komunikat jest wymagany tylko wtedy, gdy warunek to false
.
Debug.Assert(true, $"{r.ToString()}");
Wprowadzona wersja
6.0 RC 1
Typ zmiany powodującej niezgodność
Ta zmiana może mieć wpływ na zgodność źródła.
Przyczyna wprowadzenia zmiany
Ta zmiana została wprowadzona w celu zwiększenia wydajności.
Zalecana akcja
Ciągi interpolowane używane z metodami Debug nie powinny mutować stanu udostępnionego. (Te metody są również warunkowe dla stałej DEBUG
kompilacji). Jeśli z jakiegoś powodu ważne jest zachowanie starego zachowania, dodaj rzutowanie (string)
przed ciągiem interpolowanym. Rzutowanie wymusza powiązanie kompilatora z istniejącym przeciążeniem i gwarantuje, że ciąg jest zawsze zmaterializowany.
Dotyczy interfejsów API
- 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)