Ich erweitere ein Paket, um .NET 5.0 zu unterstützen, und bin auf eine grundlegende Änderung gestoßen. Angesichts der Konsolenanwendung:
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var actual = "Detail of supported commands\n============\n## Documentation produced for DelegateDecompiler, version 0.28.0 on Thursday, 22 October 2020 16:03\n\r\nThis file documents what linq commands **DelegateDecompiler** supports when\r\nworking with [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core/) (EF).\r\nEF has one of the best implementations for converting Linq `IQueryable<>` commands into database\r\naccess commands, in EF's case T-SQL. Therefore it is a good candidate for using in our tests.\r\n\r\nThis documentation was produced by compaired direct EF Linq queries against the same query implemented\r\nas a DelegateDecompiler's `Computed` properties. This produces a Supported/Not Supported flag\r\non each command type tested. Tests are groups and ordered to try and make finding things\r\neasier.\r\n\r\nSo, if you want to use DelegateDecompiler and are not sure whether the linq command\r\nyou want to use will work then clone this project and write your own tests.\r\n(See [How to add a test](HowToAddMoreTests.md) documentation on how to do this). \r\nIf there is a problem then please fork the repository and add your own tests. \r\nThat will make it much easier to diagnose your issue.\r\n\r\n*Note: The test suite has only recently been set up and has only a handful of tests at the moment.\r\nMore will appear as we move forward.*\r\n\r\n\r\n### Group: Unit Test Group\n#### [My Unit Test1](../TestGroup01UnitTestGroup/Test01MyUnitTest1):\n- Supported\n * Good1 (line 1)\n * Good2 (line 2)\n\r\n#### [My Unit Test2](../TestGroup01UnitTestGroup/Test01MyUnitTest2):\n- Supported\n * Good1 (line 1)\n * Good2 (line 2)\n\r\n\r\n\nThe End\n";
var expected = "\n#### [My Unit Test2](";
Console.WriteLine($"actual.Contains(expected): {actual.Contains(expected)}");
Console.WriteLine($"actual.IndexOf(expected): {actual.IndexOf(expected)}");
}
}
}
Ich erhalte unterschiedliche Ergebnisse basierend auf der Laufzeit von .NET Core 3.0 -> .NET 5.0:
.NET Core 3.0:
actual.Contains(expected): True
actual.IndexOf(expected): 1475
.NET 5.0:
actual.Contains(expected): True
actual.IndexOf(expected): -1
Windows 10 Pro Build 19041 x64
.NET Core 3.1.9
.NET 5.0.0-rc.2.20475.5
Ja, es hat über .NET Core 3.1.9 funktioniert
@ Tarekgh
Kennzeichnen von Abonnenten dieses Bereichs: @tarekgh , @safern , @krwq
Informationen finden Sie unter area-owners.md, wenn Sie abonniert werden möchten.
Dies ist beabsichtigt, da wir in .NET 5.0 auf der Intensivstation anstelle von NLS gewechselt haben. Weitere Informationen finden Sie unter https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu .
Sie haben die Möglichkeit, den Konfigurationsschalter System.Globalization.UseNls
zu verwenden, um zum alten Verhalten zurückzukehren. Wir empfehlen dies jedoch nicht, da die Intensivstation korrekter ist und die Verwendung der Intensivstation die Konsistenz zwischen den Betriebssystemen gewährleistet.
Ich habe vergessen zu sagen, wenn Sie möchten, dass sich IndexOf
als Contains
verhält, sollten Sie zu diesem Zeitpunkt ordinale Vergleiche verwenden.
C#
actual.IndexOf(expected, StringComparison.Ordinal)
Sie haben die Möglichkeit, den Konfigurationsschalter System.Globalization.UseNls zu verwenden, um zum alten Verhalten zurückzukehren. Wir empfehlen dies jedoch nicht, da die Intensivstation korrekter ist und die Verwendung der Intensivstation die Konsistenz zwischen den Betriebssystemen gewährleistet.
Ja, wenn Sie diesen Code unter Unix ausführen und auf netcoreapp3.1
abzielen, sehen Sie dasselbe Verhalten:
santifdezm DESKTOP-1J7TFMI ~ experimental indexof $ /home/santifdezm/experimental/indexof/bin/Debug/netcoreapp3.1/linux-x64/publish/indexof
actual.Contains(expected): True
actual.IndexOf(expected): -1
und als @tarekgh mit Ordinal
Vergleich gibt es das erwartete Ergebnis zurück.
santifdezm DESKTOP-1J7TFMI ~ experimental indexof $ /home/santifdezm/experimental/indexof/bin/Debug/net5.0/linux-x64/publish/indexof
actual.Contains(expected): True
actual.IndexOf(expected): 1475
Ich denke, dies schlägt fehl, weil die Mischung aus \r\n
und \n
in der Quellzeichenfolge. Wenn ich alle Instanzen von \r\n
durch \n
ersetze, funktioniert es. Gleiches gilt, wenn ich alles \r\n
mache. Es ist nur die Mischung, die zu unterschiedlichen Ergebnissen aus dem Vergleich auf der Intensivstation führt.
Wie auf Twitter berichtet, war das Problem, dass innerhalb der 5.0-Laufzeit wiederholte Aufrufe von string.IndexOf mit denselben Eingaben bei jedem Aufruf unterschiedliche Ergebnisse ergaben.
https://twitter.com/jbogard/status/1319381273585061890?s=21
Edit: Oben war ein Missverständnis.
@GrabYourPitchforks können wir dann den Titel der Ausgabe aktualisieren? Da dies technisch gesehen eine bahnbrechende Änderung ist, geschieht dies unter Windows und Unix ... richtig?
Ich habe Jimmy zur Klärung offline angerufen. Es ist möglich, dass ich seinen ursprünglichen Themenbericht falsch verstanden habe. 280-Zeichen-Foren sind nicht immer effizient darin, Fehler klar zu kommunizieren. ;)
Zur Verdeutlichung führt die API Contains
eine Ordnungsoperation durch. IndexOf
ohne Zeichenfolgenvergleichsflags ist eine sprachliche Operation und keine Ordnungszahl. Wenn Sie das Verhalten von Contains mit IndexOf vergleichen möchten, müssen Sie IndexOf(expected, StringComparison.Ordinal)
.
Wenn Sie mehr über den Unterschied erfahren möchten, ist
Ich habe auf Twitter Klarstellungen erhalten. Die App ruft nicht IndexOf
in einer Schleife auf. Dies ist nur ein Standardbericht über Verhaltensunterschiede zwischen 3.0 und 5.0.
@GrabYourPitchforks Könnten Sie den Link https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu in Ihren Twitter-Antworten teilen und erwähnen, dass wir einen Konfigurationsschalter haben, um zum alten Verhalten zurückzukehren?
Ich habe auf Twitter Klarstellungen erhalten. Die App ruft IndexOf nicht in einer Schleife auf. Dies ist nur ein Standardbericht über Verhaltensunterschiede zwischen 3.0 und 5.0.
Vielen Dank, @GrabYourPitchforks ... basierend darauf, schließen Sie es wie beabsichtigt.
Um hier mehr hinzuzufügen, können Sie dies tun, wenn Sie das alte Verhalten erhalten möchten, ohne wieder zu NLS zu wechseln
`` `C #
CultureInfo.CurrentCulture.CompareInfo.IndexOf (tatsächlich, erwartet, CompareOptions.IgnoreSymbols)
or
```C#
actual.IndexOf(expected, StringComparison.Ordinal)
Anstatt von
C#
actual.IndexOf(expected)
und Sie sollten das gewünschte Verhalten erhalten.
Ich kann in der verknüpften Dokumentation zur Intensivstation (https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/) nichts über \r\n
vs \n
Globalisierung-icu).
War es wirklich eine geplante Änderung?
@ForNeVeR wird es schwierig sein, jeden einzelnen Unterschied zwischen ICU und NLS Contains
mit IndexOf
ohne die StringComparison-Parameter zu vergleichen. Ich habe oben einige Möglichkeiten aufgelistet, wie Sie das vorherige Verhalten erhalten können, wenn dies gewünscht wird. Aus dem Bericht zu diesem Problem geht hervor, dass für die Verwendung von IndexOf die Option Ordinal verwendet werden sollte, und es ist in diesem Fall falsch, die sprachlichen Vergleiche zu verwenden. Die Verwendung eines sprachlichen Vergleichs kann in einem solchen Fall von der aktuellen Kultur abhängen, die in unterschiedlichen Umgebungen zu unterschiedlichen Ergebnissen führen kann.
War es wirklich eine geplante Änderung?
Ja, der Wechsel zur Intensivstation ist aus verschiedenen Gründen eine absichtliche Änderung. Windows fördert derzeit die Verwendung der Intensivstation über NLS. Intensivstation ist sowieso die Zukunft. Außerdem bietet die Intensivstation die Möglichkeit, unter Windows / Linux / OSX oder auf allen unterstützten Plattformen konsistente Verhaltensweisen zu erzielen. Durch die Verwendung der Intensivstation können die Apps das Globalisierungsverhalten anpassen, wenn sie dies wünschen.
Wie im Dokument angegeben, haben Sie weiterhin die Möglichkeit, zu altem Verhalten zurückzukehren, wenn Sie möchten.
Autsch, das Dokument, auf das verwiesen wird, besagt, dass das ICU / NLS-Verhalten unter Windows möglicherweise stillschweigend wechselt, basierend auf der Verfügbarkeit von icu.dll
in der tatsächlichen Umgebung. Dies könnte für veröffentlichte eigenständige Apps eine große Überraschung sein. Ich würde erwarten, dass .NET ICU ausliefert, um dieses Problem zu umgehen, wenn der Switch ausgewählt wurde und da ICU nicht in allen Zielumgebungen verfügbar ist. Diese optionale Laufzeitabhängigkeit macht die Dinge noch lustiger.
Ich würde erwarten, dass .NET ICU ausliefert, um dieses Problem zu umgehen, wenn der Switch ausgewählt wurde und da ICU nicht in allen Zielumgebungen verfügbar ist. Diese optionale Laufzeitabhängigkeit macht die Dinge noch lustiger.
Die Intensivstation wird jetzt als NuGet-Paket veröffentlicht. Die Apps können solche Pakete verwenden, um sicherzustellen, dass die eigenständige App über eine Intensivstation verfügt. Schauen Sie sich den Abschnitt App-Local im Dokument an . Kurz gesagt, die App hat die volle Kontrolle über das Verhalten, das sie erhalten möchten.
@tarekgh , ich stimme zu, dass die unterschiedlichen Ergebnisse zwischen Contains
und IndexOf
per se nicht das Problem sind.
Das Problem ist eindeutig IndexOf
das nicht in der Lage ist, eine Nur-ASCII-Zeichenfolge in einer anderen Nur-ASCII-Zeichenfolge zu finden (ich bin nicht sicher, ob es jemals ein Gebietsschema-abhängiges Verhalten für Nur-ASCII-Zeichenfolgen gab!).
Dies ist nichts, was ich von Änderungen im Zusammenhang mit Gebietsschema / NLS / Intensivstation erwarten würde. Tatsächlich konnte ich mir keine andere Programmiersprache / Laufzeit vorstellen, die sich so verhält.
Hier ist ein vereinfachter Testfall, der in .NET 5 RC 2 fehlerhaft ist (ich meine, was zu einem völlig unerwarteten Ergebnis führt):
var actual = "\n\r\nTest";
var expected = "\nTest";
Console.WriteLine($"actual.IndexOf(expected): {actual.IndexOf(expected)}"); // => -1
Sollte es wirklich so funktionieren? Auch warum? Was versucht es eigentlich zu tun?
War es wirklich eine geplante Änderung?
Ja, der Wechsel zur Intensivstation ist aus verschiedenen Gründen eine absichtliche Änderung.
Es tut mir leid, aber ich glaube nicht, dass dies eine geplante Änderung war, deshalb möchte ich betonen: Ich konnte mir nicht vorstellen, dass jemand eine solche Änderung plant. Leute vom .NET-Team saßen zusammen und diskutierten:
Enthält die Zeichenfolge "\ n \ r \ nTest" "\ nTest" mit aktivierter Intensivstation? Nein, eindeutig nicht!
Und niemand hat sich beschwert? Keine Chance!
Dies sieht nicht nach einer geplanten oder erwarteten Änderung aus, sondern nach einem sehr schwerwiegenden Fehler, einem großen Kompatibilitätsblocker. Aus diesem Grund funktionieren neue und portierte .NET-Anwendungen in der neuen Laufzeit nicht ordnungsgemäß, da sie keine Teilzeichenfolgen innerhalb der Zeichenfolge finden können!
Warum kümmert sich die Intensivstation überhaupt um die Leitungsenden? Haben einige Gebietsschemas ihre eigenen Gebietsschemaspezifischen Zeilenenden?
PS Ja, man könnte argumentieren, dass man wirklich immer eine Variante von kulturunabhängigem IndexOf
, wie bei der Ordnungsflagge. Aber wenn Sie sich entschlossen haben, es in .NET 5 so schwer zu brechen, können Sie es dann nicht einfach schaffen, die vernünftige, ordinale Standardeinstellung zu verwenden? Ich denke, es würde weniger Anwendungen beschädigen als die aktuelle Änderung, die wir in .NET 5 RC 2 sehen.
Ich denke auch, dass wir alle verstehen, dass es trotz IndexOf
immer kulturspezifisch verhält, Tonnen von Code in freier Wildbahn gibt, die IndexOf
ohne die Ordnungsflags und diesen Code verwenden _verwendet, um zu arbeiten_ (zumindest in einigen / den meisten Fällen). Nach dem Update von .NET 5 funktioniert es nicht mehr.
Das Problem ist eindeutig IndexOf, das nicht in der Lage ist, eine Nur-ASCII-Zeichenfolge in einer anderen Nur-ASCII-Zeichenfolge zu finden (ich bin nicht sicher, ob es jemals ein Gebietsschema-abhängiges Verhalten für Nur-ASCII-Zeichenfolgen gab!).
Es ist nicht wahr, dass ASCII vom Gebietsschema unabhängig ist. Schauen Sie sich den Link http://userguide.icu-project.org/collation/concepts als Beispiel an, wie sich das Verhalten von ASCII-Zeichen für verschiedene Kulturen unterscheiden kann.
For example, in the traditional Spanish sorting order, "ch" is considered a single letter. All words that begin with "ch" sort after all other words beginning with "c", but before words starting with "d".
Other examples of contractions are "ch" in Czech, which sorts after "h", and "lj" and "nj" in Croatian and Latin Serbian, which sort after "l" and "n" respectively.
Außerdem möchte ich klarstellen, dass die Intensivstation ihre Daten und ihr Verhalten aus dem Unicode-Standard übernimmt, der von vielen Experten gut angenommen wird. @GrabYourPitchforks wird weitere Details zu \r\n\
, über die wir hier sprechen. In der Zwischenzeit können Sie sich jedoch mit dem Dokument https://unicode.org/reports/tr29/ vertraut machen, insbesondere in den Abschnitten, in denen Folgendes erwähnt wird:
Do not break between a CR and LF. Otherwise, break before and after controls.
--
GB3 | CR | × | LF
GB4 | (Control \| CR \| LF) | ÷ |
GB5 | | ÷ | (Control \| CR \| LF)
Warum kümmert sich die Intensivstation überhaupt um die Leitungsenden? Haben einige Gebietsschemas ihre eigenen Gebietsschemaspezifischen Zeilenenden?
Dies wird im letzten Absatz angesprochen.
Es tut mir leid, aber ich glaube nicht, dass dies eine geplante Änderung war, daher möchte ich betonen: Ich konnte mir nicht vorstellen, dass jemand eine solche Änderung plant. Leute vom .NET-Team saßen zusammen und diskutierten:
Dies sieht nicht nach einer geplanten oder erwarteten Änderung aus, sondern nach einem sehr schwerwiegenden Fehler, einem großen Kompatibilitätsblocker. Aus diesem Grund funktionieren neue und portierte .NET-Anwendungen in der neuen Laufzeit nicht ordnungsgemäß, da sie keine Teilzeichenfolgen innerhalb der Zeichenfolge finden können!
Dies ist gut geplant gearbeitet und tief darin gedacht. Sie können sich das Problem https://github.com/dotnet/runtime/issues/826 ansehen, das wir vor langer Zeit veröffentlicht und öffentlich geteilt haben.
Ich möchte auch betonen, dass sich das Globalisierungsverhalten nicht nur für .NET, sondern auch für Betriebssysteme und andere Plattformen jederzeit ändern kann. Aus diesem Grund haben wir auch die App-Local-Funktion auf der Intensivstation unterstützt, damit Apps eine bestimmte ICU-Version verwenden können, um sicherzustellen, dass sich das von ihnen verwendete Verhalten nicht ändert. Eine andere Sache, Windows selbst ist dabei, die Verwendung der Intensivstation zu fördern, und eines Tages wird das Verhalten der Intensivstation das sein, was die Mehrheit der Benutzer verwenden wird.
wie mit der Ordnungsflagge. Aber wenn Sie sich entschlossen haben, es in .NET 5 so hart zu brechen, können Sie es dann nicht einfach schaffen, die vernünftige, ordinale Standardeinstellung zu verwenden? Ich denke, es würde weniger Anwendungen beschädigen als die aktuelle Änderung, die wir in .NET 5 RC 2 sehen.
Tatsächlich haben wir zuvor versucht, das Ordnungsverhalten als Standardwert während der Silverlight-Versionen festzulegen, und dies verursachte viel mehr Probleme als hier berichtet. Wir suchen nach weiteren Möglichkeiten, um den Entwicklern zu helfen, sich bewusst zu werden, wenn sie so etwas wie IndexOf
aufrufen, und absichtlich StringComparison-Flags bereitzustellen, um die Absicht auszudrücken. Wir freuen uns über Ihre Ideen.
Ich denke auch, dass wir alle verstehen, dass es trotz IndexOf, der sich immer kulturspezifisch verhält, Unmengen von Code in freier Wildbahn gibt, die IndexOf ohne die Ordnungsflags verwenden, und dieser Code funktionierte (in einigen / den meisten Fällen) mindestens). Nach dem Update von .NET 5 funktioniert es nicht mehr.
Aus diesem Grund bieten wir einen Konfigurationsschalter an, mit dem Sie auf Wunsch auch zu altem Verhalten zurückkehren können. Schauen Sie sich System.Globalization.UseNls an
@ Tarekgh , danke für die gründliche Erklärung!
Im Moment denke ich, dass es für mich besser ist, auf Details zu diesem bestimmten \r\n
-Verhalten zu warten. Mir ist nicht klar, wie IndexOf
bei dieser speziellen Suche "Grapheme Cluster Boundary Rules" verwendet (und ob dies der Fall sein sollte).
Auch wenn die Unicode-Spezifikation hier relevant ist (was sehr wohl sein kann!), Bin ich beim Lesen von https://unicode.org/reports/tr29/ nicht sicher, ob es verboten ist, die letzten \n
. Während ich die Spezifikation lese, steht dort CR | × | LF
, wobei ×
"Keine Grenze (hier keine Unterbrechung zulassen)" bedeutet. Wenn Sie also eine Sequenz \r\n\n
brechen, ist es nur verboten, die "Pause" zwischen dem ersten und dem zweiten Zeichen zu platzieren, aber es sollte in Ordnung sein, die "Pause" vor dem dritten zu platzieren, nicht wahr? Also habe ich \r\n\n
als zwei separate "Graphemcluster" gelesen, und selbst wenn IndexOf
nur mit vollständigen Graphemclustern übereinstimmen und niemals Teile von Clustern berühren muss, sollte es dennoch Teilzeichenfolge \nTest
innerhalb der Zeichenfolge \n\r\nTest
.
Sagen Sie auch, dass andere Laufzeiten / Programmiersprachen, die auf ICU- und / oder Unicode-Spezifikationen basieren, sich in diesem Beispiel gleich verhalten sollten?
Wir suchen nach weiteren Möglichkeiten, um den Entwicklern zu helfen, sich bewusst zu werden, wenn sie so etwas wie
IndexOf
aufrufen, und absichtlich StringComparison-Flags bereitzustellen, um die Absicht auszudrücken. Wir freuen uns über Ihre Ideen.
_ (Ein notwendiger Haftungsausschluss : Ich arbeite für JetBrains an mehreren Projekten, einschließlich ReSharper.) _
Ich wollte diesen Punkt anfangs nicht hierher bringen, damit er nicht wie eine Werbung klingt, aber ich denke, das ist sehr relevant, also muss ich es tun. ReSharper zeigt standardmäßig die folgende Warnung für den Benutzercode an, der IndexOf
aufruft:
_ (Bitte beachten Sie, dass mir diese spezielle ReSharper-Diagnose nicht bekannt war, bevor ich an diesem Thread beteiligt war. Daher nehme ich hier nicht teil, nur um dieses Argument vorzubringen.) _
Ich denke, es wäre eine sehr gute Idee, eine solche Benachrichtigung standardmäßig auch in jedem anderen Tool anzuzeigen oder diese gefälschte Methode mit einer solchen Benachrichtigung sogar völlig zu verwerfen.
@Niemals
Auch wenn die Unicode-Spezifikation hier relevant ist (was sehr wohl sein kann!), Bin ich mir beim Lesen von unicode.org/reports/tr29 nicht sicher, ob es verboten ist, diese letzte \ n zu finden. Während ich die Spezifikation lese, steht dort CR | × | LF, wobei × "Keine Grenze (hier keine Unterbrechung zulassen)" bedeutet. Wenn Sie also eine Sequenz unterbrechen \ r \ n \ n, ist es nur verboten, die "Unterbrechung" zwischen dem ersten und dem zweiten Zeichen zu platzieren, aber es sollte in Ordnung sein, die "Unterbrechung" vor der dritten zu platzieren, nicht wahr? Also lese ich \ r \ n \ n als zwei separate "Graphemcluster"
Das ist richtig. \r\n\n
sind 2 Cluster als \r\n
und \n
.
und selbst wenn IndexOf nur mit vollständigen Graphemclustern übereinstimmen und niemals Teile von Clustern berühren muss, sollte es dennoch Teilstring \ nTest innerhalb des Strings \ n \ r \ nTest finden.
Das ist falsch. \n\r\nTest
wird in die Teile aufgeteilt. \n
, \r\n
und Test
. Es ist offensichtlich, dass \nTest
nicht Teil dieser Zeichenfolge sein kann. Denken Sie daran, den Cluster \r\n
durch ein Symbol X
ersetzen. Jetzt ist die Quellzeichenfolge \nXTest
die nicht \nTest
.
Sagen Sie auch, dass andere Laufzeiten / Programmiersprachen, die auf ICU- und / oder Unicode-Spezifikationen basieren, sich in diesem Beispiel gleich verhalten sollten?
Wenn Sie die Standardkollatierungsstärke verwenden, lautet die Antwort Ja. Auf der Intensivstation kann die Stärke geändert werden, was sich auf das Ergebnis auswirken kann. Zum Beispiel, wie ich bereits erwähnt habe, etwas tun wie:
CultureInfo.CurrentCulture.CompareInfo.IndexOf(actual, expected, CompareOptions.IgnoreSymbols)
ändert die Stärke und lässt die Operation die Symbole ignorieren (wodurch sich das Verhalten von \n
und \r
ändert, da es zu diesem Zeitpunkt ignoriert wird).
Außerdem habe ich eine reine native ICU-C-App geschrieben und den gleichen Fall ausgeführt:
void SearchString(const char *target, int32_t targetLength, const char *source, int32_t sourceLength)
{
static UChar usource[100];
static UChar utarget[100];
u_charsToUChars(source, usource, sourceLength);
u_charsToUChars(target, utarget, targetLength);
UErrorCode status = U_ZERO_ERROR;
UStringSearch* pSearcher = usearch_open(utarget, targetLength, usource, sourceLength, "en_US", nullptr, &status);
if (!U_SUCCESS(status))
{
printf("usearch_open failed with %d\n", status);
return;
}
int32_t index = usearch_next(pSearcher, &status);
if (!U_SUCCESS(status))
{
printf("usearch_next failed with %d\n", status);
return;
}
printf("search result = %d\n", index);
usearch_close(pSearcher);
}
int main()
{
SearchString("\nT", 2, "\r\nT", 3);
SearchString("\nT", 2, "\n\nT", 3);
}
Diese App gibt die Ergebnisse aus:
search result = -1
search result = 1
Dies ist identisch mit dem Verhalten, das Sie mit .NET sehen.
Im Moment denke ich, es ist besser für mich, auf Details zu diesem bestimmten \ r \ n Verhalten zu warten. Mir ist nicht klar, wie IndexOf bei dieser Suche "Grapheme Cluster Boundary Rules" verwendet (und ob dies der Fall sein sollte).
Sicherlich wirkt sich das Clustering auf den Sortiervorgang aus. Wenn Sie sich http://unicode.org/reports/tr29/tr29-7.html ansehen, heißt es eindeutig Folgendes:
Grapheme clusters include, but are not limited to, combining character sequences such as (g + °), digraphs such as Slovak “ch”, and sequences with letter modifiers such as kw.
Graphemclustergrenzen sind wichtig für die Sortierung , regular-expressions, and counting “character” positions within text. Word boundaries, line boundaries and sentence boundaries do not occur within a grapheme cluster. In this section, the Unicode Standard provides a determination of where the default grapheme boundaries fall in a string of characters. This algorithm can be tailored for specific locales or other customizations, which is what is done in providing contracting characters in collation tailoring tables.
Ich bin mir nicht sicher, ob es weitere Details geben wird, aber ich werde @GrabYourPitchforks kommentieren lassen, wenn er hier mehr hinzuzufügen hat.
Ich denke, es wäre eine sehr gute Idee, eine solche Benachrichtigung standardmäßig auch in jedem anderen Tool anzuzeigen oder diese gefälschte Methode mit einer solchen Benachrichtigung sogar völlig zu verwerfen.
Vielen Dank!
Dies ist die gleiche Richtung, in die wir auch denken.
Um meinetwillen habe ich die verschiedenen Überladungen zwischen den Versionen verglichen:
| Methode | netcoreapp3.1
| net5.0
|
| --------------------------------------------- --------------- | ----------------- | ---------- |
| actual.Contains(expected)
| Richtig | Richtig |
| actual.IndexOf(expected)
| 1475 | -1 |
| actual.Contains(expected, StringComparison.CurrentCulture)
| Richtig | Falsch |
| actual.IndexOf(expected, StringComparison.CurrentCulture)
| 1475 | -1 |
| actual.Contains(expected, StringComparison.Ordinal)
| Richtig | Richtig |
| actual.IndexOf(expected, StringComparison.Ordinal)
| 1475 | 1475 |
| actual.Contains(expected, StringComparison.InvariantCulture)
| Richtig | Falsch |
| actual.IndexOf(expected, StringComparison.InvariantCulture)
| 1475 | -1 |
Bitte fügen Sie dazu einen Analysator bei.
Dies scheint eine dieser Änderungen zu sein, die zwar auf lange Sicht gut sind, aber nach dem Start von .NET 5 eine enorme Abwanderung verursachen. Wenn sich das Verhalten dieser Methoden zwischen .NET 5 und .NET Core 3.1 unterscheidet, was passiert, wenn .NET 5 ein Objekt aufruft, das in einer .NET Standard 2.0-Bibliothek definiert ist und ein darin übergebenes string
manipuliert von der .NET-Call-Site? Wird das alte Verhalten verwendet oder das neue Verhalten?
@ Aaronontheweb neues Verhalten. Ich habe dies anfangs aus einer Behauptung in NUnit3 gesehen, die auf netstandard2.0
abzielt. Nach dem Upgrade schlug mein Test fehl, als ich nur das Zielframework änderte.
Das ist nicht großartig - ich kann nicht steuern, was ältere Bibliotheken, auf die ich verweise, tun, wenn ich ein Upgrade durchführen möchte.
Wie viele Apps erkennen das in Unit-Tests nicht und setzen es in Produktion?
Hat das .NET-Team die Schmerzen, Probleme und Kosten berücksichtigt, die dies verursachen könnte?
Das ist nicht großartig - ich kann nicht steuern, was ältere Bibliotheken, auf die ich verweise, tun, wenn ich ein Upgrade durchführen möchte.
schöne Falle!
glückliche Zeitverschwendung durch die Jagd auf seltsame Käfer 🎉
Aber warum hilft InvariantGlobalization bei diesem Problem nicht?
Bitte fügen Sie dazu einen Analysator bei.
Ja. Und vergessen Sie nicht die F # -Unterstützung.
Wie viele Apps erkennen das in Unit-Tests nicht?
Null - da Unit-Tests nicht dazu gedacht sind, externe Bibliotheken / Frameworks wie die .NET BCL selbst zu testen.
Meiner Ansicht nach sollte es ein Attribut auf Assembly-Ebene geben, das den Modus dieser Verhaltensänderung steuern kann. Zumindest dann können Sie es auf Baugruppenebene aktivieren / deaktivieren. Dies bedeutet dann, dass auch das .NET Standard-Problem behoben ist.
Das ist nicht großartig - ich kann nicht steuern, was ältere Bibliotheken, auf die ich verweise, tun, wenn ich ein Upgrade durchführen möchte.
Ich verstehe nicht, warum du es nicht kontrollieren kannst. Alle Zeichenfolgenvergleiche verwenden entweder ICU oder NLS. Sie können die Intensivstation mit dem kompatiblen Schalter deaktivieren, wenn Sie möchten, und alle Ihre Bibliotheken werden auf das alte Verhalten zurückgesetzt.
Sie können sich nicht darauf verlassen, dass die Globalisierungsdaten über die Zeit stabil bleiben. Nehmen Sie es vom Windows-Team, dass sie keine Angst haben, Menschen zu brechen, die auf stabile Globalisierungsdaten angewiesen sind. Globalisierungsfunktionen sollten eine Black Box sein; Ich halte es nicht für sinnvoll, dass Bibliotheken (insbesondere solche, die auf .NET Standard abzielen) sagen, dass sie von solchen Implementierungsdetails abhängen.
Ich bin sicher, dass sich genauso viele Leute über .NET-Globalisierungsfunktionen beschwert haben, die unter Windows und Linux unterschiedliche Ergebnisse liefern (und vielleicht haben noch mehr Leute es noch nicht einmal bemerkt). Es ist besser, das Verhalten zwischen Windows und anderen Plattformen zu vereinheitlichen, und jeder korrekte Code sollte nicht darauf beruhen, dass Globalisierungsdaten unveränderlich sind, unabhängig davon.
Würden Sie eine grundlegende Änderung in Betracht ziehen, um auch StringComparison.Ordinal
zur Standardvergleichsstrategie zu machen? Da die Globalisierung so instabil ist, ist es sinnvoll, dass zumindest die Standardimplementierung stattdessen einen stabilen Algorithmus verwendet. Ich bin bereit zu wetten, dass 99,9% der Leute, die string.Equals(...)
oder string.Contains(...)
usw. verwenden, ohne StringComparison
bestehen, dies nicht mit der ausdrücklichen Absicht tun, mit seltsamen Macken umzugehen, die damit zusammenhängen Gebietsschemas.
Edit: Ich denke meine Frage wurde bereits beantwortet:
Tatsächlich haben wir zuvor versucht, das Ordnungsverhalten als Standardwert während der Silverlight-Versionen festzulegen, und dies verursachte viel mehr Probleme als hier berichtet. Wir suchen nach weiteren Möglichkeiten, um den Entwicklern zu helfen, beim Aufrufen von IndexOf bewusst zu werden und absichtlich StringComparison-Flags bereitzustellen, um die Absicht auszudrücken. Wir freuen uns über Ihre Ideen.
Sie können die Intensivstation mit dem kompatiblen Schalter deaktivieren, wenn Sie möchten, und alle Ihre Bibliotheken werden auf das alte Verhalten zurückgesetzt.
Ich mache Bibliotheken für den Lebensunterhalt, keine Anwendungen. Ich würde es vorziehen, eine Kompilierungsmethode zu haben, um dies zu handhaben.
Die meiste Arbeit, die wir machen, ist InvariantCulture
, was nach meinem vorherigen Verständnis von Natur aus unveränderlich sein soll. Es sieht so aus, als ob sich IndexOf
unter diesen Umständen auch zwischen .NET 5.0 und .NET Core 3.1 unterscheidet.
Wie kann ein Analysator bei bestehenden Projekten helfen?
@petarrepac das ist auch eine C # -nur Sache.
@isaacabraham und VB auch;)
Ich würde es vorziehen, eine Kompilierungsmethode zu haben, um dies zu handhaben.
@Aaronontheweb Sie haben eine Möglichkeit zur Kompilierung, dies zu handhaben (beim Kompilieren von Apps). Sie können dies Ihrem Projekt hinzufügen:
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>
BEARBEITEN: Dies gilt nur für Apps, die eine Bibliothek verbrauchen. Leider können Sie dies beim Schreiben einer Bibliothek nicht steuern.
Langfristig fördert das Windows-Team den Wechsel auf die Intensivstation. Irgendwann wird die Intensivstation die Globalisierungsgeschichte sein, und wir sind nur ein dünner Wrapper um Betriebssystembibliotheken.
Was passiert, wenn .NET 5 ein in einer .NET Standard 2.0-Bibliothek definiertes Objekt aufruft, das eine von der .NET-Aufrufseite übergebene Zeichenfolge bearbeitet? Wird das alte Verhalten verwendet oder das neue Verhalten?
Das neue Verhalten wird verwendet, da es von der Laufzeit abhängt und .NET Standard nur ein Standard für die Implementierung von Laufzeiten ist. Beachten Sie jedoch, dass dies zu einer Plattformkonsistenz zwischen Unix und Windows führt. Wenn Sie dieselben Bibliotheken ausführen, über die in Unix Bedenken bestehen, erhalten Sie das Ergebnis ICU
da ICU
die Unterstützung ist Bibliothek in Unix.
@reflectronic ist in allen Punkten richtig https://github.com/dotnet/runtime/issues/43736#issuecomment -716681586.
Um die hier erwähnten @ https://github.com/dotnet/runtime/issues/43736#issuecomment -716527590, können Sie die Ergebnisse einfach zusammenfassen, indem Sie das Sprachverhalten zwischen Windows und der Intensivstation vergleichen. Übrigens wird die Intensivstation jetzt von vielen Anwendungen unter Windows verwendet, und es wird erwartet, dass die Nutzung zunimmt. Diese Ergebnisse schließen auch Linux mit .NET Core 3.1 und niedriger aus. Dies zeigt die Konsistenz zwischen .NET 5.0 und früheren Versionen unter Linux.
Der Punkt über die Bibliothek, die früher funktionierte, wird beschädigt. Dies ist nicht vollständig richtig, da solche Bibliotheken bereits unter Linux fehlerhaft waren.
Würden Sie eine grundlegende Änderung in Betracht ziehen, um StringComparison.Ordinal zur Standardvergleichsstrategie zu machen?
Ich habe bereits erwähnt, dass wir das bereits zuvor versucht haben, aber die Anzahl der Beschwerden war sehr groß, sodass wir sie nicht anwenden konnten. Wir suchen nach Möglichkeiten, Entwicklern dabei zu helfen, die Zeichenfolgenvergleichsflags beim Aufrufen der Kollatierungs-APIs bewusst anzugeben.
Ich mache Bibliotheken für den Lebensunterhalt, keine Anwendungen. Ich würde es vorziehen, eine Kompilierungsmethode zu haben, um dies zu handhaben.
Ja, in diesem Fall kann ein Analysegerät helfen. Schauen Sie sich normalerweise die Aufrufe der Kollatierungs-APIs an und schauen Sie, welche nicht die Absicht zeigten, eine ordinale oder sprachliche Operation zu verwenden.
Wie kann ein Analysator bei bestehenden Projekten helfen?
Analysatoren scannen den Code und erkennen die Aufrufe von Kollatierungs-APIs, die keine Flags übergeben. Dies hilft, solche Aufrufe zu überprüfen und zu beheben, wenn ein Problem festgestellt wird.
das ist auch nur eine C # -Sache.
Die Änderung befindet sich in der .NET-Laufzeit, die global und nicht auf C # beschränkt sein sollte.
@tarekgh Wie manifestiert sich ein C #
Die meiste Arbeit, die wir machen, ist
InvariantCulture
, was nach meinem vorherigen Verständnis von Natur aus unveränderlich sein soll.
Kritisch war es vor dieser Änderung unmöglich, sich für plattformübergreifenden Code tatsächlich darauf zu verlassen. Wie sich NLS und Intensivstation verhalten, selbst wenn eine invariante Kultur verwendet wird, ist nicht immer dasselbe (wie dieses Problem zeigt). Wie @tarekgh sagte, hat sich dieser Code unter Linux die ganze Zeit anders
Dies mag überraschen, aber wir haben im Laufe der Jahre Dutzende von Fehlern im Zusammenhang mit Plattformunterschieden aufgrund von Benutzerberichten gefunden und behoben, wie ich sicher bin, dass viele andere Bibliotheksautoren dies seit Jahren tun.
Ich bin einfach nicht begeistert von der Aussicht, dass .NET 5 eine neue Ernte unbekannter Unbekannter einführt und diese Korrekturen nicht nur für meine Bibliotheken, sondern auch für unsere nachgelagerten Abhängigkeiten überprüft. Das sind erhebliche wirtschaftliche Kosten für uns, die für unsere Benutzer keine neuen Produktivitätsverbesserungen bewirken. Jemand in MSFT sollte dies in seiner Kosten-Nutzen-Diskussion berücksichtigen, um diese Änderung vorzunehmen.
Edit: wie, ich bekomme schon die technischen Vorzüge - ja, danke. Bitte helfen Sie dabei, die nicht offensichtlichen wirtschaftlichen Vorteile dieser Änderung im Gegensatz zu den Kosten zu verkaufen. Warum sollten Benutzer den Sprung wagen und auf .NET 5 aktualisieren, wenn man bedenkt, wie ein Rattennest dieses Problem zu sein scheint?
@tarekgh Wie manifestiert sich ein C #
Wir können C # und VB mit einem einzigen Analysator abdecken (wir bemühen uns, unsere Analysatoren wo immer möglich sprachunabhängig zu machen), aber wir können derzeit keine Analysatorabdeckung für F # erhalten.
@Aaronontheweb Jeder, der kulturelle Funktionen nutzt und davon https://docs.microsoft.com/en-us/archive/blogs/shawnste/locale-culture-data-churn vom Windows-Team an, in dem sich auch das NLS-Verhalten ändert, um Verbesserungen zu erzielen. Hier geht es also nicht mehr darum, auf die Intensivstation zu wechseln, als nur falsche Annahmen aus der Sicht der Apps / Bibliotheken zu erfassen. Ein Upgrade auf 5.0 entspricht dem Upgrade auf andere frühere Versionen. Apps werden viele neue coole Funktionen erhalten und Apps müssen getestet werden, da es einige bahnbrechende Änderungen zwischen den Versionen geben kann. Ich denke nicht, dass die Änderung des Globalisierungsverhaltens wirklich bricht, da wir immer sagen, dass sich die Globalisierung jederzeit zwischen Betriebssystem- und Betriebssystemversionen ändern kann. Wie bereits erwähnt, können Sie mit dem Konfigurationsschalter ein Upgrade auf 5.0 durchführen, wobei Sie weiterhin NLS verwenden. Dadurch wird die Intensivstation nicht wirklich zu einem Faktor bei der Upgrade-Entscheidung. Mit der Intensivstation haben die Apps jetzt die Möglichkeit, mehr Konsistenz zwischen den Betriebssystemen zu erzielen, und können sogar mehr Kontrolle über das Globalisierungsverhalten haben, wenn sie sich für die Verwendung der app-lokalen Intensivstation entscheiden. Wir bieten den Apps viel mehr Kontrolle als zuvor.
Verwandte: https://github.com/dotnet/runtime/issues/43802
(In diesem Problem wird IndexOf
_per se_ nicht erfasst. Es werden vielmehr die unbeabsichtigten Folgen der Routine Compare
erörtert, die standardmäßig einen kulturbewussten Vergleicher verwendet.)
Wie kann ein Analysator bei bestehenden Projekten helfen?
Analysatoren scannen den Code und erkennen die Aufrufe von Kollatierungs-APIs, die keine Flags übergeben. Dies hilft, solche Aufrufe zu überprüfen und zu beheben, wenn ein Problem festgestellt wird.
Ich denke, Analysatoren müssen dem csproj hinzugefügt werden.
Dies geschieht nicht automatisch. Daher werden viele vorhandene Projekte ohne diese Analysegeräte auf .NET 5 verschoben.
Außerdem hilft es, wie bereits erwähnt, nicht bei F # -Projekten.
@ Jeffhandley Danke, das bestätigt, was ich bereits verstanden habe. Es ist daher wichtig anzuerkennen, dass die mögliche "Problemumgehung" F # -Nutzern nicht hilft (ein kleiner Markt, der jedoch von MS als erstklassiger Bürger von .NET vollständig unterstützt wird). Ich habe keine Ahnung, was das bedeutet:
Die Änderung befindet sich in der .NET-Laufzeit, die global und nicht auf C # beschränkt sein sollte.
Ich habe keine Ahnung, was das bedeutet:
Die Änderung befindet sich in der .NET-Laufzeit, die global und nicht auf C # beschränkt sein sollte.
Ich meinte, dass jede Sprache, die .NET-Laufzeit verwendet, betroffen ist und nicht nur C #.
Ich werde meine Meinung noch einmal nachdrücklich zum Ausdruck bringen, dass es sofort einen Analysator geben sollte, um diese Fallstricke in der neuen Welt aufzudecken, insbesondere wenn geplant ist, das aktuelle Verhalten zu ändern.
Ich verstehe die technischen Vorzüge vollständig und schlage nicht vor, dass Sie keine Änderung vornehmen (langfristig scheint dies der richtige Schritt zu sein). Ich sage auch nicht, dass es nicht bereits als Best Practice dokumentiert wurde. Was ich damit sagen will, ist, dass dies wirklich ein großer, roter, blinkender Fehler für Entwickler sein muss, die versuchen, auf .NET 5 umzusteigen. Standardmäßig gehen Entwickler davon aus, dass dies ansonsten "einfach funktioniert".
Derzeit können Sie diese Roslyn Analyzer-Bibliothek von https://github.com/meziantou/Meziantou.Analyzer/tree/master/docs.
In diesem speziellen Fall wird ein MA0074 ausgelöst - Vermeiden Sie implizite kultursensitive Methoden
Abgesehen davon, dass dies wirklich out of the box sein muss, habe ich diese Roslyn-Ausgabe hier geöffnet: https://github.com/dotnet/roslyn-analyzers/issues/4367
@tarekgh Danke für die Klarstellung. Mein ursprünglicher Punkt war, dass Analysegeräte hier nicht die Antwort sind, wenn Sie nach einer Lösung suchen, die für alle .NET-Benutzer funktioniert.
Wir suchen nach weiteren Möglichkeiten, um den Entwicklern zu helfen, beim Aufrufen von IndexOf bewusst zu werden und absichtlich StringComparison-Flags bereitzustellen, um die Absicht auszudrücken. Wir freuen uns über Ihre Ideen.
Wie wäre es, die alten Methoden zu verwerfen (unter Verwendung eines [Obsolete]
-Attributs)?
Was passiert mit der .NET Standard-Kompatibilität, wenn die API-Oberfläche identisch ist, sich das Verhalten jedoch ändert?
Eine Änderung, um Graphemcluster zu ehren, stört mich nicht, solange die Auswirkungen gut dokumentiert sind. Eine Änderung, die dazu führt, dass sich eng verwandte Mitglieder der Familie der Zeichenfolgenmethoden inkonsistent verhalten.
Jemand, der informelles String-Munging durchführt, ohne Rücksicht auf die Unklarheiten von Zeichen, Graphemclustern oder Gebietsschemas, würde davon ausgehen, dass es nicht erforderlich ist, das Ergebnis von str.IndexOf (was auch immer) zu überprüfen, wenn str.Contains (was auch immer) erfolgreich ist ) weil uns gerade gesagt wurde, dass es dort drin ist und daher gefunden werden kann. Es spielt keine Rolle, welcher zweite Parameter, den sie nicht kennen möchten, der Standard ist, da sich der Standard sicher für alle Methoden gleich verhält, sodass sie nicht alle Feinheiten studieren müssen, um sie überhaupt zu verwenden.
Inkonsistenzen wie diese führen zu einer Sprache, die nur von Experten erfolgreich verwendet werden kann und die Leute entfremdet, die aus dem Codelager kommen. Erhöhen Sie nicht die Messlatte, um auf diese Weise einzutreten.
Ich stimme @lupestro zu. Die Inkonsistenz im Methodenverhalten ist sehr besorgniserregend. Wenn Sie langjährige Methoden haben, die sowohl unterschiedlich als auch inkonsistent wirken, wird es viel Traurigkeit geben. Die Leute werden darauf stoßen, sie werden sich von der API betrogen fühlen und sich dann fragen, welche anderen Zeitbomben darauf warten, explodiert zu werden. Viele würden .NET-Adoptierte sein, die C # über diese Art von Problem abschreiben. Es scheint, dass Sie entweder Überladungen entfernen sollten, die kein Gebietsschema akzeptieren, oder das Standardgebietsschema für Methoden normalisieren sollten. Es gibt bereits ein Compare und CompareOrdinal, möglicherweise wird ein (Last) IndexOf (Any) und (Last) IndexOf (Any) Ordinal benötigt. Ich mag diese Lösung nicht, aber zumindest würde sie mit dem übereinstimmen, was derzeit existiert. Vielleicht sollte die Idee der ordinalen Verwendung in Zeichenfolgen abgeschrieben werden. Wenn ich zwischen schnell und richtig wählen muss, wähle ich jedes Mal 'richtig'. Inkonsistente, nicht intuitive Verhaltensweisen sind äußerst frustrierend.
Ich sehe, dass dieses Problem bereits geschlossen ist, und ich nehme an, dass bereits entschieden wurde, dass dies in .NET 5.0 fortgesetzt wird. Ich weiß, dass dieses Zeug schwierig ist und dass sich Kulturinformationen (wie die Zeit) aus allen möglichen nichttechnischen Gründen ändern können. Entwickler müssen sich dessen bewusst sein, aber sie müssen sich auch auf ihre APIs verlassen, um selbstkonsistent zu sein. Es sollte mindestens eine Warnung (in 5.0) geben, auf die @aolszowka hinweist und die auf ein Problem hinweist ... und was noch wichtiger ist, warum es ein Problem ist. Es ist wichtig, vorwärts zu kommen, und manchmal bedeutet dies, dass Sie alte Verhaltensweisen / Annahmen "brechen" müssen. Dies bedeutet nicht, dass neue Inkonsistenzen eingeführt werden müssen. Diese Änderung bricht sowohl die Erwartungen als auch den Code. Wenn es nicht möglich ist, die Methoden konsistent zu machen, wäre es mir viel lieber, wenn CultureInfo explizit wäre (was ich dann über eine Erweiterungsmethode beheben könnte), als nur die Möglichkeit zu haben, dass ein nicht intuitiver Fehler meinen Code währenddessen in die Luft jagt ein stressiger Entwicklungszyklus oder das Schlimmste bei einer Kundeninstallation.
TLDR: Ändern Sie Dinge, die geändert werden müssen, aber machen Sie die API dazu nicht inkonsistent. Wenn Sie es brechen wollen, ersetzen Sie es durch etwas Besseres.
Ich benutze .NET seit Jahren und verwende bei diesen Funktionen immer standardmäßig InvariantCulture. In Bezug auf andere Sprachen als Englisch waren mir immer Zeichenpaare bekannt, die als Aliase für andere sprachspezifische Buchstaben dienen, und die zusätzliche Arbeit, die bei der Suche nach diesen Paaren beim Vergleich mit CurrentCulture als Standard anfällt. Dies hat mich zum Beispiel gebissen, wenn ich ASP.NET-Code schreibe, der die CurrentCulture des Threads basierend auf der vom Browser gesendeten bevorzugten Sprache des Benutzers festlegt, und die Vergleiche für einen Benutzer, der kein Englisch verwendet, führen dazu, dass der Code auf subtile Weise unterbrochen wird, insbesondere wenn Zeichenfolgen eine Mischung aus vom Benutzer eingegebenem (sprachlichem) und ordinalem Text enthalten.
Dieses Verhalten des Unicode-Graphemclusters ist für mich neu, da ich ein Ordnungsverhalten für Zeilenvorschübe und Wagenrückläufe erwartet hätte, selbst wenn ich wie üblich invariante Überladungen verwendet hätte. Es scheint mir, dass das Verhalten, das sowohl mehr Arbeit leistet als auch Expertenwissen erfordert , ein Opt-In-Verhalten sein sollte, unabhängig von der technischen Gerechtigkeit. Vielleicht ist dieses Schiff vor langer Zeit gesegelt, aber diese bahnbrechende Änderung sollte so transparent gemacht werden wie zum Beispiel Sprachänderungen, ohne einen obskuren Blog lesen zu müssen. Meine Kollegen sind sich der neuen C # 9.0-Funktionen kaum bewusst, geschweige denn einer geheimen ICU-Regel, die sich auf den Code auswirken kann, den sie heute schreiben und der möglicherweise eines Tages in .NET 5 (oder wahrscheinlicher in .NET 6 oder 7) portiert und kompiliert wird.
Das Veralten der alten Methoden ist eine Sache, über die wir nachdenken. Ich habe gestern Abend einen Entwurf des Vorschlags fertiggestellt und kaufe ihn zur internen Überprüfung ein. In einigen Stunden werde ich ihn hier als neue Ausgabe veröffentlichen.
Der Entwurf wird unter https://github.com/dotnet/runtime/issues/43956 veröffentlicht. Es listet verschiedene Alternativen für mögliche Wege nach vorne auf (einschließlich Nichtstun) und wägt die Vor- und Nachteile jedes Ansatzes ab. Bitte hinterlassen Sie dort Feedback zu den vorgeschlagenen Maßnahmen.
Wenn Sie einen Fehler melden, reichen Sie bitte ein neues Problem ein und beschreiben Sie den Fehler anhand dieses neuen Problems.
Wenn Sie Kommentare zu diesem bestimmten Problem haben ( "\r\n"
vs. "\n"
), antworten Sie bitte weiterhin in diesem Thread. Vielen Dank!
Wiedereröffnung, während wir die im Dokument von @GrabYourPitchforks beschriebenen Ansätze betrachten.
Wir hören Sie - hier gibt es viele klare Rückmeldungen - wir arbeiten daran, den richtigen Weg zu finden, und wir werden dieses Problem auf dem neuesten Stand halten.
Eine Änderung, um Graphemcluster zu ehren, stört mich nicht, solange die Auswirkungen gut dokumentiert sind. Eine Änderung, die dazu führt, dass sich eng verwandte Mitglieder der Familie der Zeichenfolgenmethoden inkonsistent verhalten.
Jemand, der informelles String-Munging durchführt, ohne Rücksicht auf die Unklarheiten von Zeichen, Graphemclustern oder Gebietsschemas, würde davon ausgehen, dass es nicht erforderlich ist, das Ergebnis von str.IndexOf (was auch immer) zu überprüfen, wenn str.Contains (was auch immer) erfolgreich ist ) weil uns gerade gesagt wurde, dass es dort drin ist und daher gefunden werden kann. Es spielt keine Rolle, welcher zweite Parameter, den sie nicht kennen möchten, der Standard ist, da der Standard sicher das gleiche Verhalten über alle Methoden hinweg verhält, sodass sie nicht alle Feinheiten studieren müssen, um sie überhaupt zu verwenden.
Inkonsistenzen wie diese führen zu einer Sprache, die nur von Experten erfolgreich verwendet werden kann und die Leute entfremdet, die aus dem Codelager kommen. Erhöhen Sie nicht die Messlatte, um auf diese Weise einzutreten.
Ja, das hat meine Bedenken voll zum Ausdruck gebracht. Als typischer chinesischer Entwickler setzen wir selten StringComparison
oder CultureInfo
explizit ein, wenn wir in unseren Anwendungscodes stringbezogene Methoden aufrufen, und das funktioniert einfach. Wir erwarten definitiv kein anderes Verhalten zwischen IndexOf
und Contains
!
.net 5.0
.net core 3.1
.net Framework
Ich stimme @lupestro zu. Die Inkonsistenz im Methodenverhalten ist sehr besorgniserregend. Wenn Sie langjährige Methoden haben, die sowohl unterschiedlich als auch inkonsistent wirken, wird es viel Traurigkeit geben.
Vielleicht ist ein entscheidender Punkt hier, dass die beiden Methoden immer inkonsistent waren. Sie wurden in .NET 5.0 nicht plötzlich inkonsistent. Wenn ich die Dinge richtig verfolge, hat IndexOf
immer den aktuellen Kulturvergleich verwendet, Contains
hat immer den Ordnungsvergleich verwendet. Zugegeben, .NET 5.0 fügt mehr Inkonsistenz hinzu. Der Fehler hier lag jedoch im ursprünglichen API-Design, das diese Inkonsistenz zuließ.
Wenn ich die Dinge richtig verfolge, hat IndexOf immer den Ordnungsvergleich verwendet, Contains hat immer den aktuellen Kulturvergleich verwendet. Zugegeben, .NET 5.0 fügt mehr Inkonsistenz hinzu. Der Fehler hier lag jedoch im ursprünglichen API-Design, das diese Inkonsistenz zuließ.
Das ist richtig, aber es ist umgekehrt, IndexOf(string)
verwendet die aktuelle Kultur, IndexOf(char)
verwendet Ordinal und Contains
verwendet Ordinal.
Ich werde kurz auf die Unterschiede zwischen IndexOf
und Contains
eingehen, auf die andere kürzlich hingewiesen haben.
IndexOf(string)
hat immer einen _CurrentCulture_-Vergleich angenommen, und Contains(string)
hat immer einen _Ordinal_-Vergleich angenommen. Diese Diskrepanz bestand bereits in .NET Framework. Es handelt sich nicht um eine neue Diskrepanz, die in .NET 5 eingeführt wurde. Beispielsweise werden in .NET Framework (das die NLS-Funktion von Windows verwendet) die Ligatur "æ" und die Zeichenfolge mit zwei Zeichen "ae" unter einem Sprachvergleich als gleich verglichen. Dies führt zu folgender Diskrepanz:
// Sample on .NET Framework, showing Contains & IndexOf returning inconsistent results
Console.WriteLine("encyclopædia".Contains("ae")); // prints 'False'
Console.WriteLine("encyclopædie".IndexOf("ae")); // prints '8' (my machine is set to en-US)
Diese Diskrepanz besteht seit über einem Jahrzehnt. Es ist dokumentiert und es gibt Anleitungen dazu. Ist es ein falsches Design? Vielleicht. Unter https://github.com/dotnet/runtime/issues/43956 diskutieren wir Möglichkeiten, wie das Ökosystem in Zukunft gesünder werden kann.
Für dieses spezielle Thema fragen wir uns wirklich: "Angesichts der Tatsache, dass die Diskrepanz seit jeher besteht, wie weit dürfen diese beiden Methoden in der Praxis abweichen, bevor sie das größere Ökosystem schädigen?" Ich denke, wir versuchen immer noch zu definieren, wo diese Schwelle liegen soll. Berichte wie diese sind äußerst hilfreich, da sie uns einen Einblick geben, wie Menschen diese APIs in der Praxis verwenden und welche Erwartungen Kunden an ihr Verhalten haben. Als Verwalter des Frameworks müssen wir nicht nur die technische Dokumentation berücksichtigen, sondern auch die Art und Weise, wie reale Apps diese APIs verwenden.
Dieser Kommentar ist nicht wirklich dazu gedacht, einen bestimmten Standpunkt zu verteidigen. Meine Absicht ist es, einige Missverständnisse zu klären, die ich gesehen habe, und zu erklären, wie wir das Problem umrahmt haben.
Selbst wenn InvariantCulture angegeben ist, ist es korrekt, dass \n
in der ICU-Version nicht übereinstimmt?
Vielleicht zeigt der folgende Code 5 unter Linux und -1 unter Windows an, wenn wir git und seine Standardeinstellungen verwenden (autocrlf = true)?
using System;
var s = @"hello
world";
Console.WriteLine(s.IndexOf("\n", StringComparison.InvariantCulture));
@ufcpp Ja, pro Intensivstation ist dies das erwartete Verhalten, wie weiter oben in diesem Thread erläutert. Die beiden Zeichen <CR><LF>
wenn sie nebeneinander auftreten, werden für sprachliche Zwecke als unzerbrechliche Einheit betrachtet. Die Suche nach <LF>
mit einem Sprachvergleicher (wie _InvariantCulture_) führt zu keiner Übereinstimmung, da diese unzerbrechliche Einheit aufgeteilt würde.
Ich möchte ein Update mit allen teilen: Wir haben beschlossen, die Intensivstation als Standard für 5.0 GA beizubehalten. Wir werden versuchen, die Gefahr einer versehentlichen Verwendung des Sprachvergleichs zu verbessern, wenn die Ordnungszahl beabsichtigt war. Dies wird unter https://github.com/dotnet/runtime/issues/43956 nachverfolgt
Dies war eine sehr schwierige Entscheidung, und wir mussten die Auswirkungen der Kompatibilität auf das Ökosystem gegen das Streben nach plattformübergreifender Standardisierung abwägen.
Wir werden dieses Problem offen lassen, um eine weitere Minderung des \r\n
-Problems bei der Wartung in Betracht zu ziehen, wenn festgestellt wird, dass die aktuellen Minderungen nicht ausreichen.
Ich möchte die Leute auch ermutigen, weiterhin Probleme zu melden, die infolge des Wechsels auf der Intensivstation auftreten, auch wenn das Verhalten möglicherweise eine bekannte Ursache hat. Dies bedeutet jedoch nicht, dass es "beabsichtigt" ist. Wir werden weiterhin Unterschiede untersuchen und die Grundursache verstehen und feststellen, ob wir Änderungen an ICU oder .NET vornehmen müssen, um sie zu beheben.
Es gibt eine Analyserregel, um StringComparison immer anzugeben.
https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1307
Ich möchte ein Update mit allen teilen: Wir haben beschlossen, die Intensivstation als Standard für 5.0 GA beizubehalten. Wir werden versuchen, die Gefahr einer versehentlichen Verwendung des Sprachvergleichs zu verbessern, wenn die Ordnungszahl beabsichtigt war, die in # 43956 verfolgt wird. Wir werden uns auch an einige der Bibliotheken wenden, die wir als von diesem Problem betroffen identifiziert haben. In den kommenden Tagen werden wir weitere Dokumente zur kommenden Version 5.0 veröffentlichen, mit denen Benutzer problematischen Code besser identifizieren und beheben können, um dieses Problem zu vermeiden.
Dies war eine sehr schwierige Entscheidung, und wir mussten die Auswirkungen der Kompatibilität auf das Ökosystem gegen das Streben nach plattformübergreifender Standardisierung abwägen.
Wir werden dieses Problem offen lassen, um eine weitere Minderung des
\r\n
-Problems bei der Wartung in Betracht zu ziehen, wenn festgestellt wird, dass die aktuellen Minderungen nicht ausreichen.Ich möchte die Leute auch ermutigen, weiterhin Probleme zu melden, die infolge des Wechsels auf der Intensivstation auftreten, auch wenn das Verhalten möglicherweise eine bekannte Ursache hat. Dies bedeutet jedoch nicht, dass es "beabsichtigt" ist. Wir werden weiterhin Unterschiede untersuchen und die Grundursache verstehen und feststellen, ob wir Änderungen an ICU oder .NET vornehmen müssen, um sie zu beheben.
Ich würde gerne wissen, ob ich noch .NET Standard-Abhängigkeiten verwenden kann, über die ich keine Kontrolle habe.
Ich vermute, ich werde es nicht können. Wie wäre es, wenn Sie sicherstellen, dass Benutzer auf .NET Standard 2.2 umsteigen, ich weiß nicht? API ändern?
Damit ich sicher weiß, dass ich das erwartete Verhalten bekomme.
Ich bin mir nicht sicher, wie wir es sonst vermeiden können, das derzeitige Ökosystem zu zerstören, das bereits einen angemessenen Anteil an Problemen hat.
Ich wäre froh, wenn ich mich als falsch erweisen würde, bitte tue dies mit Vorurteilen - es würde meine Gedanken beruhigen :)
@rcollina
Ich würde gerne wissen, ob ich noch .NET Standard-Abhängigkeiten verwenden kann, über die ich keine Kontrolle habe.
.Net Standard-Bibliotheken sollten im Allgemeinen plattformübergreifend sein. Und wenn eine Bibliothek heute unter .Net Core 3 unter Unix (das ICU verwendet) korrekt funktioniert, funktioniert sie mit ziemlicher Sicherheit auch unter .Net 5 unter Windows (das auch ICU verwendet).
.NET Standard 2.2
.Net Standard vNext existiert effektiv, obwohl es ".Net 5.0" heißt. (Wenn Sie also eine Bibliothek schreiben und sich nicht für die Unterstützung älterer Frameworks interessieren, würden Sie heute auf .Net Standard 2.1 abzielen. In einem Monat würden Sie stattdessen auf .Net 5.0 abzielen.)
@svick Ich
Ich entschuldige mich, bin mir aber immer noch nicht sicher, was passiert, wenn ich auf eine .NET Standard 2.1-Bibliothek verweise, die auf einer bereits vorhandenen Verhaltensinkonsistenz zwischen IndexOf und Contains beruht.
Was sich hier ändert, ist etwas Außergewöhnliches, ICU versus NLS. Diese Änderung vergrößert die Diskrepanz, die wir bereits hatten, und bricht die Erwartungen.
Es gibt nichts, was diese Informationen in Bibliotheken verschlüsselt.
Ich nehme nicht an, alle Implikationen zu verstehen, aber ich kann das Gefühl nicht abschütteln, dass wir „technisch korrekt“ sind, ohne einen nahtlosen Einstiegspfad zur neuen Normalität. Welches wird dringend benötigt.
Wie bereits erwähnt, sind sich die meisten Menschen nicht einmal neuer Sprachfunktionen bewusst, geschweige denn seismischer Änderungen wie diese, die von unseren besten Community-Mitgliedern zufällig entdeckt wurden. Wie hoch sind die Chancen, dass wir dem standhalten können?
Ich würde gerne wissen, ob ich noch .NET Standard-Abhängigkeiten verwenden kann, über die ich keine Kontrolle habe.
Was sich hier ändert, ist etwas Außergewöhnliches, ICU versus NLS. Diese Änderung vergrößert die Diskrepanz, die wir bereits hatten, und bricht die Erwartungen.
Nein, das tut es nicht. Es kann hier nicht genug betont werden, dass die Intensivstation immer unter Unix verwendet wurde. .NET Standard-Bibliotheken sollten von Natur aus portierbar sein, und alles, was zuvor unter Linux .NET Core 3.x funktioniert hat, funktioniert in .NET 5.
Die meiste Arbeit, die wir machen, ist InvariantCulture, die nach meinem bisherigen Verständnis von Natur aus unveränderlich sein soll.
Nicht wahr. InvariantCulture soll nur die Spracheinstellung des Benutzers ignorieren. Es kann sich weiterhin ändern, wenn Aktualisierungen der Unicode-Spezifikation oder der Globalisierungsbibliotheken usw. vorgenommen werden.
Hat das .NET-Team die Schmerzen, Probleme und Kosten berücksichtigt, die dies verursachen könnte?
Solche Bemerkungen ärgern mich bis zum Äußersten. Jeder Code, der plötzlich mit dieser Änderung bricht, war anfangs falsch. Wie soll sich die Plattform weiterentwickeln, wenn das .NET-Team das Verhalten von Benutzercode beibehalten muss, der falsch ist oder sich auf Implementierungsdetails stützt? Es ist nicht so, als hätten sie keinen Kompatibilitätsschalter bereitgestellt. Ein großer Teil des Grundes, warum .NET Core aus .NET Framework ausgegliedert wurde, bestand darin, dieses Problem durch Funktionen wie Side-by-Side-Installationen und app-lokale Laufzeitbereitstellungen zu lösen. Wenn Sie aus diesem Grund nicht zu .NET 5 wechseln können, wechseln Sie nicht zu .NET 5.
Ich bin einfach nicht begeistert von der Aussicht, dass .NET 5 eine neue Ernte unbekannter Unbekannter einführt und diese Korrekturen nicht nur für meine Bibliotheken, sondern auch für unsere nachgelagerten Abhängigkeiten überprüft.
Wenn Sie alle Ihre Plattformunterschieds-Fehler beseitigt haben, wie Sie behaupten, sollten Sie sich keine Sorgen machen müssen.
Hat das .NET-Team die Schmerzen, Probleme und Kosten berücksichtigt, die dies verursachen könnte?
Solche Bemerkungen ärgern mich bis zum Äußersten.
Millionen von Projekten werden unter .NET ausgeführt, und die Manipulation von Zeichenfolgen ist eine sehr häufige Operation.
Der Aufwand, den das .NET-Team benötigt, um dies zu beheben / zu ändern, ist im Vergleich zum Aufwand, der erforderlich ist, um den gesamten vorhandenen Code zu überprüfen, der auf .NET 5/6 migriert wird, winzig.
Es ist also ziemlich fair, nach dem "Plan" zu fragen, um dies anzugehen.
Gibt es einen Plan?
Wurde die Auswirkung dieser Änderung geschätzt?
Sind es 0,001% aller Projekte? Ist es 75%?
Was sind andere ähnliche Änderungen, von denen wir nichts wissen?
Möglicherweise betrifft dies nur eine kleine Anzahl von Projekten.
Aber wurde es geschätzt?
Übrigens, ich bin alle dafür, Änderungen zu brechen, wenn Grund genug ist. Wir brauchen aber auch einen Migrationspfad, der nicht zu riskant ist.
@petarrepac Versteh mich nicht falsch, das verstehe ich. Aber wie bereits mehrfach in diesem Thread erwähnt:
Angesichts der letzten beiden Punkte ist es wahrscheinlich vernünftig anzunehmen, dass dies einen relativ kleinen Prozentsatz der Projekte betrifft.
Es ist zu 100% fair, danach zu fragen, aber die Leute, die Kommentare wie den von mir zitierten schreiben, gehen oft nur davon aus, dass keine Überlegungen angestellt und geschrieben wurden, bevor sie versuchen, das Gesamtbild hinter der Änderung zu verstehen.
Hallo alle. Wir wollten eine kurze Zusammenfassung der Maßnahmen geben, die wir ergriffen haben, als dieses Problem aufgetreten ist, und am Ende, warum wir beschlossen haben, die Standardeinstellung für das Windows 10 Mai 2019-Update oder höher beizubehalten, um ICU für .NET 5.0 zu sein.
Als das Problem eröffnet wurde, haben wir einige interne Diskussionen über die möglichen Auswirkungen und Schmerzen begonnen, die dies mit unseren Kunden hätte haben können, da die Inkonsistenz zwischen Contains(string)
was Ordinal
und IndexOf(string)
kulturbewusst sein und andere APIs standardmäßig kulturbewusst sein, wenn über eine Zeichenfolge gearbeitet wird, aber Ordinal
wenn über Span<char>
oder ReadOnlySpan<char>
. Nach Diskussionen über dieses Problem haben wir begonnen, möglicherweise betroffene NuGet-Pakete zu analysieren und Daten zu sammeln, um ein klares Bild zu erhalten. Dies waren unsere Ergebnisse:
Von diesen 2040 Paketen mit einer gefährdeten Call-Site unterstützen nur 539 eine Version von .NET Standard oder .NET Core, was bedeutet, dass nur 0,54% der in NuGet.org aufgelisteten Pakete wahrscheinlich der Unterbrechung ausgesetzt sind.
Wir haben uns Pakete in der Liste der 539 potenziell betroffenen Paket-IDs angesehen, um eine Vorstellung von den tatsächlichen Auswirkungen auf diese zu erhalten. Wir haben uns die Top 70 angesehen (nach Download-Anzahl), 20 haben das Muster in der neuesten Version nicht verfügbar gemacht, von denen, die das Muster enthüllt haben, konnten wir nur 32 mit einer zulässigen Lizenz betrachten:
Dies bedeutet, dass von den Top-70-Paketen per Download nur 18% potenziell betroffen waren.
Diese Prozentsätze sind gestapelt und nicht gegen die Gesamtzahl der Pakete auf NuGet.org, die 229.536 beträgt. Wenn wir also die Gesamtzahl der Pakete und die Gesamtzahl der Downloads in NuGet.org verwenden würden, würden wir 539 potenziell betroffene Pakete von 229.536 betrachten, was 0,24% entspricht.
Und während es für uns großartig ist, Bibliotheken zu analysieren, repräsentiert Nuget nur einen kleinen Bruchteil des C # -Codes da draußen. Und selbst wenn jemand den Code besitzt, sind a) Fehler möglicherweise nicht leicht aufzuspüren, und b) sie haben möglicherweise nicht mehr die Quelle.
Dies war jedoch eine gute Datenquelle, um zu dem Schluss zu gelangen, dass dies zwar eine sehr bemerkenswerte Verhaltensänderung sein könnte, es sich jedoch um eine Unterbrechung handelt, die bereits unter Unix beim Lesen von Eingaben aufgetreten ist, die möglicherweise Windows-Zeilenenden enthalten (die möglicherweise nicht so häufig sind).
In .NET Core und .NET 5+ streben wir nach Konsistenz zwischen allen Betriebssystemen. Angesichts der Auswirkungen dieser Änderung schien dies das Richtige zu sein. Wir kümmern uns um die Kompatibilität und bieten daher einen kompatiblen Laufzeitschalter, damit die Benutzer zu ihrem alten Verhalten zurückkehren können.
Als Schlussfolgerung aus den Paketen, die wir überprüfen konnten, da das Verhalten unter Unix bereits anders ist, haben wir eine Menge defensiver Programmierung gegen dieses Problem gesehen, um mögliche Unterbrechungen zwischen Betriebssystemen zu verringern.
Hinzu kommt, dass sich die Globalisierung jederzeit ändern kann, da wir ein dünner Wrapper für das gesamte Betriebssystem sind. Daher schien es im Moment das Richtige zu sein, auf allen von uns unterstützten Betriebssystemen nur der gleiche Wrapper zu sein.
Als Teil davon haben wir unsere Dokumentation mit praktischen Beispielen, Roslyn Analyzer-Regeln und der Frage, wie betroffener Code dies abschwächen kann, verbessert.
Vielen Dank für all Ihr wertvolles Feedback, da es uns immer an einen besseren Ort bringt und wir versuchen werden, diese Erfahrung für .NET 6 weiter zu verbessern, wie unter https://github.com/dotnet/runtime/issues/43956 beschrieben
Da wir die Schmerzen verstehen, die dies aufgrund der Unterschiede zwischen den Zeilenenden zwischen Unix und Windows verursachen kann, halten wir dieses Problem offen und werden einen möglichen Weg untersuchen, um den Fall \r\n
für .NET 5.0 zu mildern .x, die Teil einer Wartungsfreigabe sein sollte.
Es gibt auch einen Unterschied zwischen char und string:
Console.WriteLine("com/test/test/test/a/b/ʹ$ʹ".IndexOf("$"));
Console.WriteLine("com/test/test/test/a/b/ʹ$ʹ".IndexOf('$'));
-1
24
@mattleibow führt bei Verwendung der Zeichensuche eine Ordnungssuche durch. Das Dokument https://docs.microsoft.com/en-us/dotnet/api/system.string.indexof?view=net-5.0#System_String_IndexOf_System_Char_ , in dem This method performs an ordinal (culture-insensitive) search
. Wenn Sie die Zeichenfolgensuche mit der Ordnungsoption durchführen, erhalten Sie das gleiche Ergebnis wie das Zeichen.
C#
Console.WriteLine("com/test/test/test/a/b/ʹ$ʹ".IndexOf("$", StringComparison.Ordinal));
~ Es scheint, dass CA1307 nur bei indexof(char)
ausgelöst wird , nicht aber bei indexof(string)
. Gibt es eine Regel für die string
-Version? Dies scheint wichtiger zu sein, da der Standardwert von char
automatisch die Ordnungszahl verwendet und die Änderung dies nicht wirklich beeinflusst, während sich das Verhalten von string
geändert hat und Sie die Ordnungszahl angeben müssen, um das Verhalten wiederherzustellen einige Fälle. ~
~ Wie erkennt man indexof(string)
? ~
Gefunden, es ist Regel CA1310. Unsere Dokumente sind für https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu#use -nls-anstatt-von-icu falsch und erwähnen diese spezielle Variante nicht. Ich werde diese Dokumente aktualisieren.
Hilfreichster Kommentar
@tarekgh , ich stimme zu, dass die unterschiedlichen Ergebnisse zwischen
Contains
undIndexOf
per se nicht das Problem sind.Das Problem ist eindeutig
IndexOf
das nicht in der Lage ist, eine Nur-ASCII-Zeichenfolge in einer anderen Nur-ASCII-Zeichenfolge zu finden (ich bin nicht sicher, ob es jemals ein Gebietsschema-abhängiges Verhalten für Nur-ASCII-Zeichenfolgen gab!).Dies ist nichts, was ich von Änderungen im Zusammenhang mit Gebietsschema / NLS / Intensivstation erwarten würde. Tatsächlich konnte ich mir keine andere Programmiersprache / Laufzeit vorstellen, die sich so verhält.
Hier ist ein vereinfachter Testfall, der in .NET 5 RC 2 fehlerhaft ist (ich meine, was zu einem völlig unerwarteten Ergebnis führt):
Sollte es wirklich so funktionieren? Auch warum? Was versucht es eigentlich zu tun?
Es tut mir leid, aber ich glaube nicht, dass dies eine geplante Änderung war, deshalb möchte ich betonen: Ich konnte mir nicht vorstellen, dass jemand eine solche Änderung plant. Leute vom .NET-Team saßen zusammen und diskutierten:
Und niemand hat sich beschwert? Keine Chance!
Dies sieht nicht nach einer geplanten oder erwarteten Änderung aus, sondern nach einem sehr schwerwiegenden Fehler, einem großen Kompatibilitätsblocker. Aus diesem Grund funktionieren neue und portierte .NET-Anwendungen in der neuen Laufzeit nicht ordnungsgemäß, da sie keine Teilzeichenfolgen innerhalb der Zeichenfolge finden können!
Warum kümmert sich die Intensivstation überhaupt um die Leitungsenden? Haben einige Gebietsschemas ihre eigenen Gebietsschemaspezifischen Zeilenenden?
PS Ja, man könnte argumentieren, dass man wirklich immer eine Variante von kulturunabhängigem
IndexOf
, wie bei der Ordnungsflagge. Aber wenn Sie sich entschlossen haben, es in .NET 5 so schwer zu brechen, können Sie es dann nicht einfach schaffen, die vernünftige, ordinale Standardeinstellung zu verwenden? Ich denke, es würde weniger Anwendungen beschädigen als die aktuelle Änderung, die wir in .NET 5 RC 2 sehen.Ich denke auch, dass wir alle verstehen, dass es trotz
IndexOf
immer kulturspezifisch verhält, Tonnen von Code in freier Wildbahn gibt, dieIndexOf
ohne die Ordnungsflags und diesen Code verwenden _verwendet, um zu arbeiten_ (zumindest in einigen / den meisten Fällen). Nach dem Update von .NET 5 funktioniert es nicht mehr.