Udostępnij za pośrednictwem


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.

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