Skip to content

Commit a33cd57

Browse files
authored
System.Globalization.CompareOptions update (#10087)
1 parent 1ca77b5 commit a33cd57

File tree

13 files changed

+497
-275
lines changed

13 files changed

+497
-275
lines changed

snippets/cpp/VS_Snippets_CLR_System/system.Globalization.CompareOptions.StringSort/CPP/compareoptions_stringsort.cpp

-119
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CompareOptionsExample.Run();
2+
StringSort.Run();
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<OutputType>Library</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
66
</PropertyGroup>
77

88
</Project>
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,51 @@
1-
// The following code example shows how sorting with CompareOptions.StringSort differs from sorting without CompareOptions.StringSort.
2-
3-
// <snippet1>
4-
using System;
5-
using System.Collections;
1+
using System;
2+
using System.Collections.Generic;
63
using System.Globalization;
74

8-
public class SamplesCompareOptions {
9-
10-
private class MyStringComparer: IComparer {
11-
private CompareInfo myComp;
12-
private CompareOptions myOptions = CompareOptions.None;
13-
14-
// Constructs a comparer using the specified CompareOptions.
15-
public MyStringComparer( CompareInfo cmpi, CompareOptions options ) {
16-
myComp = cmpi;
17-
this.myOptions = options;
18-
}
19-
20-
// Compares strings with the CompareOptions specified in the constructor.
21-
public int Compare(Object a, Object b) {
22-
if (a == b) return 0;
23-
if (a == null) return -1;
24-
if (b == null) return 1;
25-
26-
String sa = a as String;
27-
String sb = b as String;
28-
if (sa != null && sb != null)
29-
return myComp.Compare(sa, sb, myOptions);
30-
throw new ArgumentException("a and b should be strings.");
31-
}
32-
}
33-
34-
public static void Main() {
35-
36-
// Creates and initializes an array of strings to sort.
37-
String[] myArr = new String[9] { "cant", "bill's", "coop", "cannot", "billet", "can't", "con", "bills", "co-op" };
38-
Console.WriteLine( "\nInitially," );
39-
foreach ( String myStr in myArr )
40-
Console.WriteLine( myStr );
41-
42-
// Creates and initializes a Comparer to use.
43-
//CultureInfo myCI = new CultureInfo( "en-US", false );
44-
MyStringComparer myComp = new MyStringComparer(CompareInfo.GetCompareInfo("en-US"), CompareOptions.None);
45-
46-
// Sorts the array without StringSort.
47-
Array.Sort( myArr, myComp );
48-
Console.WriteLine( "\nAfter sorting without CompareOptions.StringSort:" );
49-
foreach ( String myStr in myArr )
50-
Console.WriteLine( myStr );
51-
52-
// Sorts the array with StringSort.
53-
myComp = new MyStringComparer(CompareInfo.GetCompareInfo("en-US"), CompareOptions.StringSort);
54-
Array.Sort( myArr, myComp );
55-
Console.WriteLine( "\nAfter sorting with CompareOptions.StringSort:" );
56-
foreach ( String myStr in myArr )
57-
Console.WriteLine( myStr );
58-
}
5+
public class StringSort
6+
{
7+
public static void Run()
8+
{
9+
var wordList = new List<string>
10+
{
11+
"cant", "bill's", "coop", "cannot", "billet", "can't", "con", "bills", "co-op"
12+
};
13+
14+
Console.WriteLine("Before sorting:");
15+
foreach (string word in wordList)
16+
{
17+
Console.WriteLine(word);
18+
}
19+
20+
Console.WriteLine(Environment.NewLine + "After sorting with CompareOptions.None:");
21+
SortAndDisplay(wordList, CompareOptions.None);
22+
23+
Console.WriteLine(Environment.NewLine + "After sorting with CompareOptions.StringSort:");
24+
SortAndDisplay(wordList, CompareOptions.StringSort);
25+
}
26+
27+
// Sort the list of words with the supplied CompareOptions.
28+
private static void SortAndDisplay(List<string> unsorted, CompareOptions options)
29+
{
30+
// Create a copy of the original list to sort.
31+
var words = new List<string>(unsorted);
32+
// Define the CompareInfo to use to compare strings.
33+
CompareInfo comparer = CultureInfo.InvariantCulture.CompareInfo;
34+
35+
// Sort the copy with the supplied CompareOptions then display.
36+
words.Sort((str1, str2) => comparer.Compare(str1, str2, options));
37+
foreach (string word in words)
38+
{
39+
Console.WriteLine(word);
40+
}
41+
}
5942
}
6043

6144
/*
62-
This code produces the following output.
45+
CompareOptions.None and CompareOptions.StringSort provide identical ordering by default
46+
in .NET 5 and later. But in prior versions, the output is the following:
6347
64-
Initially,
48+
Before sorting:
6549
cant
6650
bill's
6751
coop
@@ -72,7 +56,7 @@ This code produces the following output.
7256
bills
7357
co-op
7458
75-
After sorting without CompareOptions.StringSort:
59+
After sorting with CompareOptions.None:
7660
billet
7761
bills
7862
bill's
@@ -93,6 +77,4 @@ This code produces the following output.
9377
co-op
9478
con
9579
coop
96-
9780
*/
98-
// </snippet1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System;
2+
using System.Globalization;
3+
4+
public class CompareOptionsExample
5+
{
6+
public static void Run()
7+
{
8+
// Uppercase and lowercase characters are equivalent (according to the culture rules)
9+
// when IgnoreCase is used.
10+
TestStringEquality("ONE two", "one TWO", "Case sensitivity", CompareOptions.IgnoreCase);
11+
12+
// Punctuation is ignored with the IgnoreSymbols option.
13+
TestStringEquality("hello world", "hello, world!", "Punctuation", CompareOptions.IgnoreSymbols);
14+
15+
// Whitespace and mathematical symbols are also ignored with IgnoreSymbols.
16+
TestStringEquality("3 + 5 = 8", "358", "Whitespace and mathematical symbols", CompareOptions.IgnoreSymbols);
17+
18+
// Caution: currency symbols and thousands separators are ignored with IgnoreSymbols.
19+
// Parse strings containing numbers/currency and compare them numerically instead.
20+
TestStringEquality("Total $15,000", "Total: £150.00", "Currency symbols, decimals and thousands separators", CompareOptions.IgnoreSymbols);
21+
22+
// Full width characters are common in East Asian languages. Use the IgnoreWidth
23+
// option to treat full- and half-width characters as equal.
24+
TestStringEquality("abc,-", "abc,-", "Half width and full width characters", CompareOptions.IgnoreWidth);
25+
26+
// The same string in Hiragana and Katakana is equal when IgnoreKanaType is used.
27+
TestStringEquality("ありがとう", "アリガトウ", "Hiragana and Katakana strings", CompareOptions.IgnoreKanaType);
28+
29+
// When comparing with the IgnoreNonSpace option, characters like diacritical marks are ignored.
30+
TestStringEquality("café", "cafe", "Diacritical marks", CompareOptions.IgnoreNonSpace);
31+
32+
// Ligature characters and their non-ligature forms compare equal with the IgnoreNonSpace option.
33+
// Note: prior to .NET 5, ligature characters were equal to their expanded forms by default.
34+
TestStringEquality("straße œuvre cæsar", "strasse oeuvre caesar", "Ligature characters", CompareOptions.IgnoreNonSpace);
35+
}
36+
37+
private static void TestStringEquality(string str1, string str2, string description, CompareOptions options)
38+
{
39+
Console.WriteLine(Environment.NewLine + description + ":");
40+
// First test with the default CompareOptions then with the provided options
41+
TestStringEquality(str1, str2, CompareOptions.None);
42+
TestStringEquality(str1, str2, options);
43+
}
44+
45+
private static void TestStringEquality(string str1, string str2, CompareOptions options)
46+
{
47+
Console.Write($" When using CompareOptions.{options}, \"{str1}\" and \"{str2}\" are ");
48+
if (string.Compare(str1, str2, CultureInfo.InvariantCulture, options) != 0)
49+
{
50+
Console.Write("not ");
51+
}
52+
Console.WriteLine("equal.");
53+
}
54+
}
55+
56+
/*
57+
In .NET 5 and later, the output is the following:
58+
59+
Case sensitivity:
60+
When using CompareOptions.None, "ONE two" and "one TWO" are not equal.
61+
When using CompareOptions.IgnoreCase, "ONE two" and "one TWO" are equal.
62+
63+
Punctuation:
64+
When using CompareOptions.None, "hello world" and "hello, world!" are not equal.
65+
When using CompareOptions.IgnoreSymbols, "hello world" and "hello, world!" are equal.
66+
67+
Whitespace and mathematical symbols:
68+
When using CompareOptions.None, "3 + 5 = 8" and "358" are not equal.
69+
When using CompareOptions.IgnoreSymbols, "3 + 5 = 8" and "358" are equal.
70+
71+
Currency symbols, decimals and thousands separators:
72+
When using CompareOptions.None, "Total $15,000" and "Total: £150.00" are not equal.
73+
When using CompareOptions.IgnoreSymbols, "Total $15,000" and "Total: £150.00" are equal.
74+
75+
Half width and full width characters:
76+
When using CompareOptions.None, "abc,-" and "abc,-" are not equal.
77+
When using CompareOptions.IgnoreWidth, "abc,-" and "abc,-" are equal.
78+
79+
Hiragana and Katakana strings:
80+
When using CompareOptions.None, "ありがとう" and "アリガトウ" are not equal.
81+
When using CompareOptions.IgnoreKanaType, "ありがとう" and "アリガトウ" are equal.
82+
83+
Diacritical marks:
84+
When using CompareOptions.None, "café" and "cafe" are not equal.
85+
When using CompareOptions.IgnoreNonSpace, "café" and "cafe" are equal.
86+
87+
Ligature characters:
88+
When using CompareOptions.None, "straße œuvre cæsar" and "strasse oeuvre caesar" are not equal.
89+
When using CompareOptions.IgnoreNonSpace, "straße œuvre cæsar" and "strasse oeuvre caesar" are equal.
90+
91+
Note: When using .NET versions prior to .NET 5, ligature characters compare as equal to their
92+
non-ligature counterparts by default, so the last test will output as follows:
93+
94+
Ligature characters:
95+
When using CompareOptions.None, "straße œuvre cæsar" and "strasse oeuvre caesar" are equal.
96+
When using CompareOptions.IgnoreNonSpace, "straße œuvre cæsar" and "strasse oeuvre caesar" are equal.
97+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Library</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Include="compareoptions_stringsort.fs" />
10+
<Compile Include="compareoptions_values.fs" />
11+
</ItemGroup>
12+
13+
</Project>

0 commit comments

Comments
 (0)