Standardmäßige Zahlenformatanalysegenauigkeit
.NET unterstützt jetzt höhere Genauigkeitswerte beim Formatieren von Zahlen als Zeichenfolgen mit ToString
und TryFormat
.
Hinweis
Die maximale Genauigkeit wurde in .NET 7 erneut geändert. Weitere Informationen finden Sie unter Maximale Genauigkeit für numerische Formatzeichenfolgen.
Änderungsbeschreibung
Beim Formatieren von Zahlen als Zeichenfolgen stellt der Genauigkeitsspezifizierer in der Formatzeichenfolge die Anzahl der Ziffern in der resultierenden Zeichenfolge dar. Je nach Formatspezifizierer, dem ersten Zeichen in der Zeichenfolge, kann die Genauigkeit die Gesamtzahl der Ziffern, die Anzahl der signifikanten Stellen oder die Anzahl der Dezimalstellen darstellen.
In früheren Versionen von .NET ist die Analyselogik für numerische Standardformate auf eine Genauigkeit von 99 oder weniger beschränkt. Einige numerische Typen haben eine höhere Genauigkeit, die von ToString(string format)
jedoch nicht ordnungsgemäß verfügbar gemacht wird. Wenn Sie eine Genauigkeit mehr als 99 angeben (z. B. 32.ToString("C100")
), wird die Formatzeichenfolge als benutzerdefinierte numerische Formatzeichenfolge anstelle von „Währung mit Genauigkeit 100“ interpretiert. In benutzerdefinierten numerischen Formatzeichenfolgen werden Zeichen als Zeichenliterale interpretiert. Außerdem wird eine Formatzeichenfolge, die einen ungültigen Formatspezifizierer enthält, je nach Genauigkeitswert unterschiedlich interpretiert. H99
löst eine FormatException-Ausnahme für den ungültigen Formatspezifizierer aus, während H100
als benutzerdefinierte numerische Formatzeichenfolge interpretiert wird.
Ab .NET 6 unterstützt .NET die Genauigkeit bis Int32.MaxValue. Eine Formatzeichenfolge, die aus einem Formatspezifizierer mit einer beliebigen Anzahl von Ziffern besteht, wird als eine dem Standard entsprechende numerische Formatzeichenfolge mit Genauigkeit interpretiert. Eine FormatException-Ausnahme wird für eine oder beide der folgenden Bedingungen ausgelöst:
- Das Formatspezifiziererzeichen ist kein Standardformatspezifizierer.
- Die Genauigkeit ist größer als Int32.MaxValue.
Diese Änderung wurde in der Analyselogik implementiert, die alle numerischen Typen betrifft.
In der folgenden Tabelle sind die Behavior Changes für verschiedene Formatzeichenfolgen aufgeführt.
Formatzeichenfolge | Vorheriges Verhalten | Verhalten ab .NET 6 |
---|---|---|
C2 |
Bezeichnet eine Währung mit zwei Dezimalstellen | Bezeichnet eine Währung mit zwei Dezimalstellen (keine Änderung) |
C100 |
Bezeichnet eine benutzerdefinierte numerische Formatzeichenfolge, die "C100" ausgibt | Bezeichnet eine Währung mit 100 Dezimalstellen |
H99 |
Löst aufgrund eines ungültigen Standardformatspezifizierers "H" eine FormatException-Ausnahme aus | Löst aufgrund eines ungültigen Standardformatspezifizierers "H" eine FormatException-Ausnahme aus (keine Änderung) |
H100 |
Bezeichnet eine benutzerdefinierte numerische Formatzeichenfolge | Löst aufgrund eines ungültigen Standardformatspezifizierers "H" eine FormatException-Ausnahme aus |
Eingeführt in Version
.NET 6
Grund für die Änderung
Durch diese Änderung wird das unerwartete Verhalten korrigiert, das bei einer höheren Genauigkeit der numerischen Formatanalyse auftritt.
Empfohlene Maßnahme
In den meisten Fällen ist keine Maßnahme erforderlich, und die richtige Genauigkeit wird in den resultierenden Zeichenfolgen angezeigt.
Wenn Sie jedoch das vorherige Verhalten wiederherstellen möchten, bei dem der Formatspezifizierer als Literalzeichen interpretiert wird, wenn der Genauigkeitswert über 99 liegt, können Sie dieses Zeichen in einfachen Anführungszeichen umschließen oder mit einem umgekehrten Schrägstrich als Escapezeichen versehen. In früheren Versionen von .NET gibt 42.ToString("G999")
beispielsweise G999
zurück. Ändern Sie die Formatzeichenfolge in "'G'999"
oder "\\G999"
, um dieses Verhalten beizubehalten. Dies funktioniert im .NET Framework, in .NET Core sowie in .NET 5 und höher.
Die folgenden Formatzeichenfolgen werden weiterhin als benutzerdefinierte numerische Formatzeichenfolgen interpretiert:
- Beginnt mit einem beliebigen Zeichen, das kein alphabetisches ASCII-Zeichen ist, z. B.
$
oderè
- Beginnt mit einem alphabetischen ASCII-Zeichen, auf das keine ASCII-Ziffer folgt, z. B.
A$
- Beginnt mit einem alphabetischen ASCII-Zeichen, gefolgt von einer ASCII-Ziffernsequenz und einem beliebigen Zeichen, das kein ASCII-Ziffernzeichen ist, z. B.
A12A
Betroffene APIs
Diese Änderung wurde in der Analyselogik implementiert, die alle numerischen Typen betrifft.
- System.Numerics.BigInteger.ToString(String)
- System.Numerics.BigInteger.ToString(String, IFormatProvider)
- System.Numerics.BigInteger.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Int32.ToString(String)
- System.Int32.ToString(String, IFormatProvider)
- System.Int32.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.UInt32.ToString(String)
- System.UInt32.ToString(String, IFormatProvider)
- System.UInt32.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Byte.ToString(String)
- System.Byte.ToString(String, IFormatProvider)
- System.Byte.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.SByte.ToString(String)
- System.SByte.ToString(String, IFormatProvider)
- System.SByte.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Int16.ToString(String)
- System.Int16.ToString(String, IFormatProvider)
- System.Int16.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.UInt16.ToString(String)
- System.UInt16.ToString(String, IFormatProvider)
- System.UInt16.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Int64.ToString(String)
- System.Int64.ToString(String, IFormatProvider)
- System.Int64.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.UInt64.ToString(String)
- System.UInt64.ToString(String, IFormatProvider)
- System.UInt64.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Half.ToString(String)
- System.Half.ToString(String, IFormatProvider)
- System.Half.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Single.ToString(String)
- System.Single.ToString(String, IFormatProvider)
- System.Single.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Double.ToString(String)
- System.Double.ToString(String, IFormatProvider)
- System.Double.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)
- System.Decimal.ToString(String)
- System.Decimal.ToString(String, IFormatProvider)
- System.Decimal.TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)