C#核心筆記——(六)框架基礎

我們在編程時所需的許多核心功能并不是由C#語言提供的,而是由.NET Framework中的類型提供的。本節我們將介紹Framework在基礎編程任務(例如虛的等值比較、順序比較以及類型轉換)中的作用。我們還會介紹Framework中的基本類型,例如String、DateTime和Enum.

本章中的絕大部分類型位于System命名空間下,但以下幾種類型除外:
1.StringBuilder類型定義在System。Text命名空間中。該命名空間中還包含用于進行文本編碼的類型。
2.CultureInfo及其相關類型定義在System.Globalization命名空間中。
2.Xmlconvert類型定義在System.Xml命名空間中。

6.1 字符串與文本處理

6.1.1 字符

C#中的一個char代表一個Unicode字符。char是System.Char的別名。在第2章中,我們介紹了如何表示char字面量,例如:

char c = 'a';
char newLine = '\n';

System.Char定義了一系列靜態方法對字符處理,例如:ToUpper、ToLower和IsWhiteSpace。這些方法既可以通過System.Char類型進行調用也可以使用其別名char進行調用:

Console.WriteLine(System.Char.ToUpper('c'));
Console.WriteLine(char.IsWhiteSpace('\t'));

ToUpper和ToLower會受到最終用戶語言環境的影響,這可能會導致微妙的缺陷。例如,下面的表達式在土耳其語言環境中會得到false值:

Console.WriteLine(char.ToUpper('i') == 'I');

因為在土耳其語中,char.ToUpprt(‘i’)的結果為‘ī’。為了避免這個問題,System.Char和System.String還提供了和語言環境無關的,有Invariant后綴的ToUpper和ToLower。它們會使用英語語言規則:

Console.WriteLine(char.ToUpperInvariant('i') == 'I');

它是以下寫法的簡化形式:

Console.WriteLine(char.ToUpper('i',System.Globalization.CultureInfo.InvariantCulture) == 'I');

char類型中有相當一部分的靜態方法用于字符分類,如表:

靜態方法包含的字符包含的Unicode分類
IsLetterA-Z,a-z和其他字母字符UpperCaseLetter LowerCaseLetter TittleCaseLetter ModifierLetter OtherLetter
IsUpper大小寫字母UpperCaseLetter
IsLower小寫字母LowerCaseLetter
IsDigit0-9和其他字母表中的數字DecimalDigitNumber
IsLetterOrDigit字母和數字IsLetter、IsDigit
IsNumber所有數字以及Unicode分數和羅馬數字符號DecimalDigitNumber LetterNumber OtherNumber
IsSeparator空格與所有Unicode分隔符LIneSeparate ParagraphSeparate
IsWhiteSpace所有分隔符,以及\n、\r、\t、\f和\vLIneSeparate ParagraphSeparate
IsPunctuation西方和其他字母表中的標點符號DashPunchtuation Connector Punctuation InitialQuote PunctuationFinalQuotePPunctuation
IsSymbol大部分其他的可打印符號MathSymbol ModifierSymbol OtherSymbol
isControl值小于0x20的不可打印的控制字符。例如\n、\r、\t、\0和0x7F與0x9A之間的字符(無)

對于更詳細的分類,char提供了一個名為GetUnicodeCategory的靜態方法,它返回一個UnicodeCategory枚舉值,它的成員即表的6-1最右邊一列的值。

我們完全由能力通過顯示轉換一個整數來制造出一個Unicode集之外的char。因此要檢測字符的有效性,可以調用char.GetUnicodeCategory方法:如果返回值為UnicodeCategory.OhterNotAssigned那么這個字符就是無效的。

一個char字符占用16給二進制位,這足以表示基本多文種平面(Basic Multilingual Plane)中的所有Unicode字符。但是如果超出了這個范圍,就必須使用替代組(Surrogate pairs)。

6.1.2 字符串

C#中的string(==System.String)是一個不可變的(不可修改)的字符序列。在第二章筆記中,我們介紹了如何表示一個字符串字面量,執行相等比較以及如何連接兩個字符串。本章我們將介紹其余字符串處理函數:System.String類的靜態和實例成員函數。

6.1.2.1 創建字符串

創建字符串的最簡單方法就是將字面量賦給一個變量,這和我們在第2章的做法一樣:

string s1 = "Hello";
string s2 = "First Line\r\nSecond Line";
string s3 = @"\\r_server\n_fileshare\t_helloworld.cs";
Console.WriteLine(s1);
Console.WriteLine(s2);
Console.WriteLine(s3);

若要創建一個重復的字符序列,可以使用string類的構造器:

Console.WriteLine(new string('*',10));//**********

我們還可以從char數組來構造一個字符串,而ToCharArray方法則執行了相反的操作:

char[] ca = "Hello".ToCharArray();
string sca = new string(ca);
Console.WriteLine(sca);//Hello

string類的重載構造器可以接收各種(不安全的)指針類型,以便從類似char*這種類型中創建字符串。

6.1.2.2 null和空字符串

空字符串指長度為零的字符串。我們可以使用字面量或靜態string.Empty字段來創建一個空字符串。若要判斷一個字符串是否為空字符串,則可以執行一個相等比較,或測試它的Length屬性:

string empty = "";
Console.WriteLine(empty == "");           //True
Console.WriteLine(empty == string.Empty); //True
Console.WriteLine(empty.Length == 0);     //True

字符串是引用類型,因此它可以為null:

string nullString = null;
Console.WriteLine(nullString == null);//True
Console.WriteLine(nullString == "");  //False
Console.WriteLine(nullString.Length == 0); //NullReferenceException

我們可以使用靜態方法string.IsNullOrEmpty來判斷一個字符串是否為null或空字符串。

6.1.2.3 訪問字符串中的字符

字符串的索引器可以返回一個指定索引位置的字符。和所有操作字符串的方法相似,索引是從0開始計數的。

string str = "abcde";
char letter = str[1];
Console.WriteLine(letter);//letter == 'b'

string還實現了IEnumerable,所以可以用foreach遍歷它的字符:

foreach (char c in "abc")
{Console.Write(c + ",");//1,2,3
}

6.1.2.4 字符串內搜索

在字符串內執行搜索的最簡單方法是StartsWith、EndsWith和Contains,這些方法均返回true或false:

Console.WriteLine("quick brown fox".StartsWith("quick"));//True
Console.WriteLine("quick brown fox".EndsWith("fox"));//True
Console.WriteLine("quick brown fox2".EndsWith("fox"));//false
Console.WriteLine("quick brown fox".EndsWith("fox"));//True
Console.WriteLine("quick brown fox".Contains("brown"));//True

StartsWith和EndsWith提供了重載方法,使用StringComparsion枚舉或者CultureInfo對象來控制大小寫和文化相關的規則。其默認行為是使用當前文化規則執行區分大小寫的匹配。以下代碼則使用了不變文化規則執行不區分大小寫的搜索:

bool isaBc = "abcdef".StartsWith("aBc", StringComparison.InvariantCultureIgnoreCase);
Console.WriteLine(isaBc); //True

Contains則沒有提供這種便利的重載方法,但是可以使用IndexOf方法實現相同的效果。

IndexOf的功能更強,它返回指定字符或者字符串的首次出現的位置(-1則表示該子字符串不存在):

Console.WriteLine("abcdef".IndexOf("cd"));

IndexOf也提供了重載方法,不但接受StringComparison枚舉值,還可以接受startPosition參數,指定初始搜索位置。

Console.WriteLine("abcde abcde".IndexOf("CD",6,StringComparison.CurrentCultureIgnoreCase));//8

LastIndexOf和IndexOf類似,只是它從后向前進行搜索的。

IndexOfAny返回和字符集中的任意一個字符第一個匹配的位置:

Console.WriteLine("ab,cd ef".IndexOfAny(new char[] { ' ',','}));//2
Console.WriteLine("pas5wOrd".IndexOfAny("0123456789".ToCharArray()));//3

LastIndexOfAny則從相反方向執行相同操作。

6.1.2.5 字符串處理

string是不可變的,因此所有“處理”字符串的方法都會返回一個新的字符串,而原始的字符串則不受影響(其效果和重新為一個字符串變量賦值一樣)。

Substring方法可以提取部分字符串:

string left3 = "12345".Substring(0,3);
string mid3 = "12345".Substring(1,3);
Console.WriteLine(left3);//123
Console.WriteLine(mid3);//234

若省略長度,則會得到剩余的字符串:

string end3 = "12345".Substring(2);
Console.WriteLine(end3);//345

Insert和Remove在特定的位置插入或者刪除一些字符:

string s1 = "helloworld".Insert(5, ",");
Console.WriteLine(s1);       //hello,world
string s2 = s1.Remove(5, 2); 
Console.WriteLine(s2);       //helloorld

PadLeft和PadRight會特定的字符(如果未指定則使用空格)將字符串填充為指定的長度:

Console.WriteLine("12345".PadLeft(9,'*')); //****12345
Console.WriteLine("12345".PadLeft(9));//    12345

如果輸入字符串長度大于填充長度,則返回不發生變化的原始字符串。

TrimStart和TrimEnd會從字符串的開始或結尾刪除指定的字符,Trim則是從開始和結尾執行刪除操作。這些方法默認會刪除空白字符(包括空格、制表符、換行和這些字符的Unicode變體):

Console.WriteLine("   abc \t\r\n ".Trim().Length);//3

Replace會替換字符串中所有(非重疊的)特定字符或子字符串:

Console.WriteLine("to be done".Replace(" "," | "));//to | be |done
Console.WriteLine("to be done".Replace(" ", ""));//tobedone

ToUpper和ToLower會返回與輸入字符串相對應的大寫和小寫字符串。默認情況下,它會受用戶當前語言設置的影響;ToUpperInvariant和ToLowerInvariant則總是應用英語字母表規則。

6.1.2.6 字符串的分割與連接

Split將字符串分割為若干部分:

string[] words = "The quick brown fox".Split();foreach (string word in words)Console.Write(word + "|"); //The|quick|brown|fox|

默認情況下,Split使用空白字符作為分隔符;重載的方法也可以接收char和string分隔符的params數組。Split還可以接受一個StringSplitOptions枚舉值以刪除空白項。這在一行文本中有多種單詞分隔符時很有用。

靜態方法Join則執行和Split相反的操作。它需要一個分隔符和字符串的數組:

string[] words = "The quick brown fox".Split();
string together = string.Join(",", words);
Console.WriteLine(together);//The,quick,brown,fox

靜態方法Concat和Join類似,但是它僅僅接受一個字符串的params數組,且不支持分隔符。Concat操作和+操作符效果完全相同(實際上編譯器會將+轉換為Concat):

string sentence = string.Concat("The", "quick", "brown", "fox");
string sameSentence = "The" + "quick" + "brown" + "fox";
Console.WriteLine(sentence);//Thequickbrownfox
Console.WriteLine(sameSentence);//Thequickbrownfox

6.1.2.7 String.Format與組合格式字符串

靜態方法Format提供了創建嵌入變量的字符串的便利方法。嵌入的變量(或值)可以時任何類型,而Format則會直接調用它們的ToString方法。

包含嵌入變量的主字符串稱為組合格式字符串。調用String.Format時,需要提供一個組合格式字符串,后面緊跟每一個嵌入的變量,例如:

string composite = "It's {0} degrees in {1} on this{2}morning";
string s = string.Format(composite, 35, "Perth", DateTime.Now.DayOfWeek);
Console.WriteLine(s); //It 's 35 degrees in Perth on thisSaturdaymorning

從C#6開始,可以使用插值字符串字面量來達成同樣的效果。只需要在字符串前面加上$符號,并將表達式寫在花括號中:

string s = $"It's hot this{DateTime.Now.DayOfWeek} morning";
Console.WriteLine(s);

花括號里面的每一個數字稱為格式項。這些數字對應參數的位置,后面可以跟隨:
1.逗號與應用的最小寬度
2.冒號與格式字符串
3.最小寬度用于對齊各個列。如果其值為負數,則左對齊,否則為右對齊,例如:

string composite = "Name={0,-20} Credit Limit={1,15:C}";
Console.WriteLine(string.Format(composite,"Mary",500));
Console.WriteLine(string.Format(composite, "Elizabeth", 20000));

運行結果:

Name=Mary                 Credit Limit=500.00
Name=Elizabeth            Credit Limit=20,000.00

如果不使用string.Format則上述方法可寫為:

string composites = "Name=" + "Mary".PadRight(20) + "Credit Limit"+ 500.ToString("C").PadLeft(15);
Console.WriteLine(composites);

上例的信用額度是通過”C“格式字符串轉換為貨幣值的。

6.1.3 字符串的比較

.NET Framework在兩個值的比較上劃分了兩個不同的概念:相等比較和順序比較。等值比較驗證兩個實例是否從語義上是相同的,而順序比較則驗證兩個實例(如果有的話)按照升序或者降序排列的話,哪一個應當首先出現。

等值比較并不是順序比較的一個子集。這兩種方法各自有不同的用途。例如,兩個不同的值卻可以有相同的排序位置。

可以使用==操作符或者string的Equals方法來進行字符串的等值比較。后者可以指定一些選項*例如不區分大小寫),因此功能更強。

另一個不同點是,如果將變量轉換為object類型,則==就不一定是按字符串處理的了。

對于字符串的順序比較則可使用實例方法CompareTo或者靜態方法Compare或CompareOrdinal:這些方法會返回一個正數、負數或者0.這取決于第一個值是在第二個值之后、之前還是同時出現。

6.1.3.1 序列比較于文化相關的字符串比較

字符串比較有兩種基本方法:序列比較(ordinal)和文化相關的比較(culture-sensitive)。序列比較會直接將字符串解析為數字(按照它們的Unicode字符數值);而文化相關的比較則參照特定的字母表來解釋字符。有兩種特殊的文化:”當前文化“,基于計算機控制面板的設定;”不變文化“,在任何計算機上都是相同的(并且和美國文化密切一致)。

對于相等比較,序列和文化相關的算法都是非常有用的。而排序時,人們則通常選擇文化相關的比較:因為當按照字符進行排序時,通常需要一個字母順序表。序列比較依賴的是Unicode的數字位置,這恰好會使英文字母按照順序排序,但即使是這樣也可能不能滿足要求。例如,在區分大小寫的情況下,考慮如下字符串”Atom“、”autom"和“Zamia"。使用不變文化則其排列順序將是:

"autom""Atom""Zamia"

而使用序列比較則為:

"Atom""Zamia""autom"

這是因為不變文化封裝了一個字母表,它認為大寫字符與其對應的小寫字符是相鄰的(aAbBcCdD…)。然而序列比較算法將所有大寫字母排列在前面,然后才是全部小寫字母(A…Z,a…z)這實際上回歸到了20世紀60年代發明的ASCII字符集了。

6.1.3.2 字符串的相等比較

結果序列比較有局限性,但是字符串的==運算符總是執行區分大小寫的序列比較。不帶有參數的string.Equals方法也是用同樣的方式。這就是string類型的”默認“相等比較的行為。

字符串的==和Equals方法選擇序列算法的原因是因為它既高效有確定。字符串相等比較是基礎操作,并遠比順序比較使用頻繁。

”嚴格“的相等概念與==運算符的一般用途是一致的。

下面的方法允許執行文化相關的大小寫比較:

public bool Equals(string value, StringComparison comparisonType);
public static bool Equals(string a, string b, StringComparison comparisonType);

我們更推薦靜態的版本因為它在兩個字符串中的一個或者全部為null的時候仍然有效。
StringComparison是枚舉類型,其定義如下:

    //// 摘要://     Specifies the culture, case, and sort rules to be used by certain overloads of//     the System.String.Compare(System.String,System.String) and System.String.Equals(System.Object)//     methods.public enum StringComparison{//// 摘要://     Compare strings using culture-sensitive sort rules and the current culture.CurrentCulture = 0,//// 摘要://     Compare strings using culture-sensitive sort rules, the current culture, and//     ignoring the case of the strings being compared.CurrentCultureIgnoreCase = 1,//// 摘要://     Compare strings using culture-sensitive sort rules and the invariant culture.InvariantCulture = 2,//// 摘要://     Compare strings using culture-sensitive sort rules, the invariant culture, and//     ignoring the case of the strings being compared.InvariantCultureIgnoreCase = 3,//// 摘要://     Compare strings using ordinal (binary) sort rules.Ordinal = 4,//// 摘要://     Compare strings using ordinal (binary) sort rules and ignoring the case of the//     strings being compared.OrdinalIgnoreCase = 5}

例如:

Console.WriteLine(string.Equals("foo","FOO", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(" " == "ǖ");
Console.WriteLine(string.Equals(" ", "ǖ", StringComparison.CurrentCulture));

上述中的第三個比較是由計算機當前語言設置決定的。

6.1.3.3 字符串的順序比較

String的實例方法CompareTo執行文化相關的區分大小寫的順序比較,與==運算符不同,CompareTo不使用序列比較。這是因為對于排序來說,文化相關的算法更為有效。
以下是方法的定義:

public int CompareTo(string strB);

實例方法CompareTo實現了IComparable泛型接口,它也是在整個.NET Framework中使用的標準比較協議。這意味著string的CompareTo定義了字符串在應用程序中,作為集合元素時排序的默認行為。
對于其他類型的比較則可以調用靜態方法Compare和CompareOrdinal:

        //// 摘要://     Compares substrings of two specified System.String objects, ignoring or honoring//     their case, and returns an integer that indicates their relative position in//     the sort order.//// 參數://   strA://     The first string to use in the comparison.////   indexA://     The position of the substring within strA.////   strB://     The second string to use in the comparison.////   indexB://     The position of the substring within strB.////   length://     The maximum number of characters in the substrings to compare.////   ignoreCase://     true to ignore case during the comparison; otherwise, false.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero – The substring in strA precedes the substring in strB in the//     sort order.//     Zero – The substrings occur in the same position in the sort order, or length//     is zero.//     Greater than zero – The substring in strA follows the substring in strB in the//     sort order.//// 異常://   T:System.ArgumentOutOfRangeException://     indexA is greater than strA.System.String.Length. -or- indexB is greater than//     strB.System.String.Length. -or- indexA, indexB, or length is negative. -or- Either//     indexA or indexB is null, and length is greater than zero.public static int Compare(String? strA, int indexA, String? strB, int indexB, int length, bool ignoreCase);//// 摘要://     Compares substrings of two specified System.String objects and returns an integer//     that indicates their relative position in the sort order.//// 參數://   strA://     The first string to use in the comparison.////   indexA://     The position of the substring within strA.////   strB://     The second string to use in the comparison.////   indexB://     The position of the substring within strB.////   length://     The maximum number of characters in the substrings to compare.//// 返回結果://     A 32-bit signed integer indicating the lexical relationship between the two comparands.//     Value – Condition//     Less than zero – The substring in strA precedes the substring in strB in the//     sort order.//     Zero – The substrings occur in the same position in the sort order, or length//     is zero.//     Greater than zero – The substring in strA follows the substring in strB in the//     sort order.//// 異常://   T:System.ArgumentOutOfRangeException://     indexA is greater than strA.System.String.Length. -or- indexB is greater than//     strB.System.String.Length. -or- indexA, indexB, or length is negative. -or- Either//     indexA or indexB is null, and length is greater than zero.public static int Compare(String? strA, int indexA, String? strB, int indexB, int length);//// 摘要://     Compares two specified System.String objects using the specified comparison options//     and culture-specific information to influence the comparison, and returns an//     integer that indicates the relationship of the two strings to each other in the//     sort order.//// 參數://   strA://     The first string to compare.////   strB://     The second string to compare.////   culture://     The culture that supplies culture-specific comparison information. If culture//     is null, the current culture is used.////   options://     Options to use when performing the comparison (such as ignoring case or symbols).//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between strA//     and strB, as shown in the following table//     Value – Condition//     Less than zero –strA precedes strB in the sort order.//     Zero –strA occurs in the same position as strB in the sort order.//     Greater than zero –strA follows strB in the sort order.//// 異常://   T:System.ArgumentException://     options is not a System.Globalization.CompareOptions value.public static int Compare(String? strA, String? strB, CultureInfo? culture, CompareOptions options);//// 摘要://     Compares two specified System.String objects, ignoring or honoring their case,//     and using culture-specific information to influence the comparison, and returns//     an integer that indicates their relative position in the sort order.//// 參數://   strA://     The first string to compare.////   strB://     The second string to compare.////   ignoreCase://     true to ignore case during the comparison; otherwise, false.////   culture://     An object that supplies culture-specific comparison information. If culture is//     null, the current culture is used.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero –strA precedes strB in the sort order.//     Zero –strA occurs in the same position as strB in the sort order.//     Greater than zero –strA follows strB in the sort order.public static int Compare(String? strA, String? strB, bool ignoreCase, CultureInfo? culture);//// 摘要://     Compares two specified System.String objects, ignoring or honoring their case,//     and returns an integer that indicates their relative position in the sort order.//// 參數://   strA://     The first string to compare.////   strB://     The second string to compare.////   ignoreCase://     true to ignore case during the comparison; otherwise, false.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero –strA precedes strB in the sort order.//     Zero –strA occurs in the same position as strB in the sort order.//     Greater than zero –strA follows strB in the sort order.public static int Compare(String? strA, String? strB, bool ignoreCase);//// 摘要://     Compares two specified System.String objects using the specified rules, and returns//     an integer that indicates their relative position in the sort order.//// 參數://   strA://     The first string to compare.////   strB://     The second string to compare.////   comparisonType://     One of the enumeration values that specifies the rules to use in the comparison.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero –strA precedes strB in the sort order.//     Zero –strA is in the same position as strB in the sort order.//     Greater than zero –strA follows strB in the sort order.//// 異常://   T:System.ArgumentException://     comparisonType is not a System.StringComparison value.////   T:System.NotSupportedException://     System.StringComparison is not supported.public static int Compare(String? strA, String? strB, StringComparison comparisonType);//// 摘要://     Compares substrings of two specified System.String objects using the specified//     rules, and returns an integer that indicates their relative position in the sort//     order.//// 參數://   strA://     The first string to use in the comparison.////   indexA://     The position of the substring within strA.////   strB://     The second string to use in the comparison.////   indexB://     The position of the substring within strB.////   length://     The maximum number of characters in the substrings to compare.////   comparisonType://     One of the enumeration values that specifies the rules to use in the comparison.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero – The substring in strA precedes the substring in strB in the//     sort order.//     Zero – The substrings occur in the same position in the sort order, or the length//     parameter is zero.//     Greater than zero – The substring in strA follows the substring in strB in the//     sort order.//// 異常://   T:System.ArgumentOutOfRangeException://     indexA is greater than strA.System.String.Length. -or- indexB is greater than//     strB.System.String.Length. -or- indexA, indexB, or length is negative. -or- Either//     indexA or indexB is null, and length is greater than zero.////   T:System.ArgumentException://     comparisonType is not a System.StringComparison value.public static int Compare(String? strA, int indexA, String? strB, int indexB, int length, StringComparison comparisonType);//// 摘要://     Compares substrings of two specified System.String objects using the specified//     comparison options and culture-specific information to influence the comparison,//     and returns an integer that indicates the relationship of the two substrings//     to each other in the sort order.//// 參數://   strA://     The first string to use in the comparison.////   indexA://     The starting position of the substring within strA.////   strB://     The second string to use in the comparison.////   indexB://     The starting position of the substring within strB.////   length://     The maximum number of characters in the substrings to compare.////   culture://     An object that supplies culture-specific comparison information. If culture is//     null, the current culture is used.////   options://     Options to use when performing the comparison (such as ignoring case or symbols).//// 返回結果://     An integer that indicates the lexical relationship between the two substrings,//     as shown in the following table.//     Value – Condition//     Less than zero – The substring in strA precedes the substring in strB in the//     sort order.//     Zero – The substrings occur in the same position in the sort order, or length//     is zero.//     Greater than zero – The substring in strA follows the substring in strB in the//     sort order.//// 異常://   T:System.ArgumentException://     options is not a System.Globalization.CompareOptions value.////   T:System.ArgumentOutOfRangeException://     indexA is greater than strA.Length. -or- indexB is greater than strB.Length.//     -or- indexA, indexB, or length is negative. -or- Either strA or strB is null,//     and length is greater than zero.public static int Compare(String? strA, int indexA, String? strB, int indexB, int length, CultureInfo? culture, CompareOptions options);//// 摘要://     Compares substrings of two specified System.String objects, ignoring or honoring//     their case and using culture-specific information to influence the comparison,//     and returns an integer that indicates their relative position in the sort order.//// 參數://   strA://     The first string to use in the comparison.////   indexA://     The position of the substring within strA.////   strB://     The second string to use in the comparison.////   indexB://     The position of the substring within strB.////   length://     The maximum number of characters in the substrings to compare.////   ignoreCase://     true to ignore case during the comparison; otherwise, false.////   culture://     An object that supplies culture-specific comparison information. If culture is//     null, the current culture is used.//// 返回結果://     An integer that indicates the lexical relationship between the two comparands.//     Value – Condition//     Less than zero – The substring in strA precedes the substring in strB in the//     sort order.//     Zero – The substrings occur in the same position in the sort order, or length//     is zero.//     Greater than zero – The substring in strA follows the substring in strB in the//     sort order.//// 異常://   T:System.ArgumentOutOfRangeException://     indexA is greater than strA.System.String.Length. -or- indexB is greater than//     strB.System.String.Length. -or- indexA, indexB, or length is negative. -or- Either//     strA or strB is null, and length is greater than zero.public static int Compare(String? strA, int indexA, String? strB, int indexB, int length, bool ignoreCase, CultureInfo? culture);//// 摘要://     Compares two specified System.String objects and returns an integer that indicates//     their relative position in the sort order.//// 參數://   strA://     The first string to compare.////   strB://     The second string to compare.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero –strA precedes strB in the sort order.//     Zero –strA occurs in the same position as strB in the sort order.//     Greater than zero –strA follows strB in the sort order.public static int Compare(String? strA, String? strB);//// 摘要://     Compares substrings of two specified System.String objects by evaluating the//     numeric values of the corresponding System.Char objects in each substring.//// 參數://   strA://     The first string to use in the comparison.////   indexA://     The starting index of the substring in strA.////   strB://     The second string to use in the comparison.////   indexB://     The starting index of the substring in strB.////   length://     The maximum number of characters in the substrings to compare.//// 返回結果://     A 32-bit signed integer that indicates the lexical relationship between the two//     comparands.//     Value – Condition//     Less than zero – The substring in strA is less than the substring in strB.//     Zero – The substrings are equal, or length is zero.//     Greater than zero – The substring in strA is greater than the substring in strB.//// 異常://   T:System.ArgumentOutOfRangeException://     strA is not null and indexA is greater than strA.System.String.Length. -or- strB//     is not null and indexB is greater than strB.System.String.Length. -or- indexA,//     indexB, or length is negative.public static int CompareOrdinal(String? strA, int indexA, String? strB, int indexB, int length);//// 摘要://     Compares two specified System.String objects by evaluating the numeric values//     of the corresponding System.Char objects in each string.//// 參數://   strA://     The first string to compare.////   strB://     The second string to compare.//// 返回結果://     An integer that indicates the lexical relationship between the two comparands.//     Value – Condition//     Less than zero –strA is less than strB.//     Zero –strA and strB are equal.//     Greater than zero –strA is greater than strB.public static int CompareOrdinal(String? strA, String? strB);

后面兩個方法,是前面兩個方法的快捷調用形式。

所有的順序比較都放回正數、負數或者零。者取決于第一個值是在第二個值之后,之前還是相同的位置:

Console.WriteLine("Boston".CompareTo("Austin"));//1
Console.WriteLine("Boston".CompareTo("Boston"));//0
Console.WriteLine("Boston".CompareTo("Chicago"));//-1
Console.WriteLine("Boston0".CompareTo("Boston1"));//-1
Console.WriteLine("Boston2".CompareTo("Boston1"));//1
Console.WriteLine("ǖ".CompareTo("ǖ"));//0
Console.WriteLine("foo".CompareTo("FOO"));//-1

以下語句使用當前文化進行不區分大小寫的比較:

Console.WriteLine(string.Compare("foo", "FOO", true));//0

6.1.4 StringBuilder

StringBuilder類(System.Text命名空間)表示一個可變(可編輯)的字符串。
StringBuilder可以直接進行子字符串的Append、Insert、Remove和Replace而不需要替換整個StringBuilder。

StringBuilder的構造器可以選擇接受一個初始字符串值,及其內部容量的初始值(默認為16個字符)。如果需要更大的容量,則StringBuilder會自動(以較小的性能代價)調整它的內部結構,以至其最大的容量(默認為int.MaxValue)。

StringBulider一般通過反復調用Append來構建較長的字符串,這比反復連接字符串類型對象要高效得多。

StringBuilder sb = new StringBuilder();
for(int i = 0; i < 50; i++)
{sb.Append(i + ",");
}
Console.WriteLine(sb.ToString());

輸出結果:

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,

在上述例子中,表達式i+","表示我們仍然在反復連接字符串。但是由于我們使用的字符串很小,因此這個操作的性能開銷非常少,并不會隨著循環迭代而增長。然而,為了實現最好的性能,我們可以將循環體修改為:

StringBuilder sb = new StringBuilder();
for(int i = 0; i < 50; i++)
{sb.Append(i);sb.Append(",");
}
Console.WriteLine(sb.ToString());

AppendLine執行Append操作,隨后添加一個換行序列(在Windows下為”\r\n“)。而AppendFormat則接受一個組合格式字符串,這和String.Format是類似的。除了Insert、Remove和Replace方法(Replace方法和字符串的Replace方法類似),StringBuilder還定義了Length屬性和一個可寫的索引器,以獲得/設置每一個字符。

如果要清除StringBuilder的內容,可以創建一個新的StringBuilder或者將其Length設置為零。

將StringBuilder的Length屬性設置為0并不會減小其內部容量。因此,如果之前StringBuilder已經包含了一百萬個字符,則它在Length設置為0后仍然占用2MB的內存。因此,如果希望釋放這些內存,則必須新建一個StringBuilder,然后將舊的對象清除出作用域(從而可以被垃圾回收)。

6.1.5 文本編碼和Unicode

字符集是一種字符配置,每一對配置包含了數字碼或者代碼點(code point)。常用的字符集由兩種:Unicode和ASCII。Unicode具有約一百萬個字符的地址空間,目前已經分配的大約有100000個。Unicode包括世界上使用最廣泛的語言、一些歷史語言及特殊符號。ASCII字符集只是Unicode字符集的前128個字符。它包括US風格鍵盤上的大多數字符。ASCII比Unicode出現早30年,有時仍以其簡單性和高效性而得到應用,它的每一個字符是用一個字節表示的。

.NET類型系統的設計使用的是Unicode字符集,但是它隱含支持ASCII字符集,因為ASCII字符集是Unicode的子集。

文本編碼(text encoding)是將字符從數字代碼點映射到二進制表示的方法。在.NET中,文本編碼主要用預處理文本文件和流。當將一個文本文件讀取到字符串時,文本編碼器(text encoder)會將文件數據從二進制轉換為char和string類型使用的內部Unicode表示。文本編碼能夠限制哪些字符被識別并影響存儲效率。

.NET的文本編碼分為兩類:
一類是將Unicode字符映射到其他字符集
一類是使用標準的Unicode編碼模式

第一類包含遺留的編碼方式,例如IBM的EBCDIC,以及包含前128個區域擴展字符的8位字符集(這種將字符集字以代碼頁進行區分的方法,在Unicode之前就已經普遍存在了)。ASCII編碼也屬于這一類:它將對前128個字符編碼,然后去掉其他字符。這個分類也包含GB18030(這種編碼方式并非遺留編碼方式),這種編碼是從2000年以后,在中國開發或者在中國銷售的應用程序的強制編碼標準。

第二類是UTF-8、UTF-16、UTF-32。每一種編碼方式在空間的使用效率都有所差別。UTF-8對于大多數文本而言是最具空間效率的:它使用1~4個字節來表示每一個字符。前128個字符只需要一個字節,這樣它就可以兼容ASCII.UTF-8是最普遍的文本文件和流編碼方式(特別是在Internet上),并且是.NET中默認的流的I/O編碼方式(事實上,它幾乎是所有語言隱含的默認編碼方式)。

UTF-16使用一個或者兩個16位字來表示一個字符,它是.NET內部表示字符和字符串的方式。有一些程序也使用UTF-16來寫入文件內容。

UTF-32是空間效率最低的:每一個代碼點直接對應一個32位數,所以每一個字符都會占用4個字節。因此,UTF-32很少使用。然而由于每一個字符都有同樣的字節數,因此它可以簡化隨機訪問操作。

6.1.5.1 獲取一個Encoding對象

System.Text中的Encoding類是封裝文本編碼的基類型。它有一些子類,封裝了具有相同特性的編碼方式。實例化一個正確配置的編碼類的最簡單方法是使用標準的IANA(互聯網數字分配機構嗎Internet Assigned Numbers Authority)字符集名稱調用Encoding.GetEncoding方法。

Encoding utf8 = Encoding.GetEncoding("utf-8");
Encoding chinese = Encoding.GetEncoding("GB18030");

最常用的編碼也可以通過調用Encoding類的特定靜態屬性獲得:

編碼名稱Encoding類的靜態屬性
UTF-8Encoding.UTF8
UTF-16Encoding.Unicode(注意不是UTF-16)
UTF-32Encoding.UTF-32
ASCIIEncoding.ASCII

靜態方法GetEncodings返回所有支持的編碼方式清單及其標準的LANA名稱:

foreach(EncodingInfo info in Encoding.GetEncodings())Console.WriteLine(info.Name);

獲取編碼方式的另一個方法是直接實例化Encoding類。這樣做可以通過構造器參數來設置各種選項,包括:
1.在解碼,如果遇到一個無效字節系列,是否拋出異常。默認為false.
2.對UTF-16/UTF-32進行編碼/解碼時是否使用最高有效字節優先(大字節存儲順序)或最低有效字節優先(小字節存儲順序,little endian)。默認值為小字節存儲順序。這也是Windows操作系統的標準。
3.是否使用字節順序標記(表示字節順序的前綴)。

6.1.5.2 文件與流I/O編碼

Encoding對象最常見的應用是控制文件或流的文本讀寫操作,例如,下面的代碼將“Testing…"以UTF-16的編碼方式寫入文件data.txt中:

System.IO.File.WriteAllText("data.txt", "testing", Encoding.Unicode);

如果省略最后一個參數,則WriteAllText會使用最普遍的UTF-8編碼方式。

UTF-8是所有文件和流I/O的默認文本編碼方式。

6.1.5.3 編碼為字節數組

Encoding對象可以將文本轉換為字節數組,反之亦然。GetBytes方法用指定的編碼方式將string轉換為byte[];而GetString則將byte[]轉換為string:

System.IO.File.WriteAllText("data.txt", "testing"

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/76333.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/76333.shtml
英文地址,請注明出處:http://en.pswp.cn/web/76333.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI——K近鄰算法

文章目錄 一、什么是K近鄰算法二、KNN算法流程總結三、Scikit-learn工具1、安裝2、導入3、簡單使用 三、距離度量1、歐式距離2、曼哈頓距離3、切比雪夫距離4、閔可夫斯基距離5、K值的選擇6、KD樹 一、什么是K近鄰算法 如果一個樣本在特征空間中的k個最相似&#xff08;即特征空…

transient關鍵字深度解析

Java transient 關鍵字深度解析 transient(意思:瞬時的,瞬間的) 1. 核心概念 (1) 基本定義 作用:標記字段不參與序列化 適用場景: 敏感數據(如密碼、密鑰) 臨時計算字段 依賴運行時環境的字段(如Thread對象) (2) 語法示例 java public class User implements Se…

信刻電子檔案藍光光盤刻錄安全檢測長期歸檔

信刻一直致力于為檔案館、各行業檔案部門&#xff0c;提供跨網數據交換、電子檔案數據磁光異質備份歸檔解決方案。所研制的電子檔案光盤智能長期歸檔系統&#xff0c;滿足國產環境下”刻、管、存、檢、用”全生命周期管理應用需求&#xff0c;能夠提供一份離線歸檔、一份近線存…

Word 中“母版頁”的等效機制

Word 和 PowerPoint 不太一樣——**Word 實際上沒有像 PowerPoint 那樣的“母版頁&#xff08;Master Page&#xff09;”**功能。但它有1個和“母版頁”功能類似的東西&#xff0c;可能造成你看到的“校徽自動出現在每一頁”的現象&#xff1a; ? Word 中“母版頁”的等效機制…

Go:反射

為什么使用反射 在編程中&#xff0c;有時需編寫函數統一處理多種值類型 &#xff0c;這些類型可能無法共享同一接口、布局未知&#xff0c;甚至在設計函數時還不存在 。 func Sprint(x interface{}) string {type stringer interface {String() string}switch x : x.(type) …

SS25001-多路復用開關板

1 概述 1.1 簡介 多路復用開關板是使用信號繼電器實現2線制的多路復用開關板卡&#xff1b;多路復用開關是一種可以將一個輸入連接到多個輸出或一個輸出連接到多個輸入的拓撲結構。這種拓撲通常用于掃描&#xff0c;適合將一系列通道自動連接到公共線路的的設備。多路復用開…

vue3 nprogress 使用

nprogress 介紹與作用 1.nprogress 是一個輕量級的進度條組件&#xff0c;主要用于在頁面加載或路由切換時顯示一個進度條&#xff0c;提升用戶體驗。它的原理是通過在頁面頂部創建一個 div&#xff0c;并使用 fixed 定位來實現進度條的效果 2.在 Vite Vue 3 項目中&#xf…

Jsp技術入門指南【六】jsp腳本原理及隱式對象

Jsp技術入門指南【六】jsp腳本原理及隱式對象 前言一、JSP 腳本元素1.1 聲明1.2 表達式1.3 腳本標簽 二、JSP 的隱式對象是什么三、隱式對象詳解outrequestsessionapplicationconfigexception 前言 在之前的博客中&#xff0c;我們已經介紹了JSP的環境搭建、編譯文件查找以及生…

vue3推薦的移動table庫

vxe-table https://gitee.com/js-class/vxe-table#https://gitee.com/link?targethttps%3A%2F%2Fvxetable.cn 文檔api https://vxetable.cn/#/component/table/other/bookkeepingVoucher 引入步驟 安裝 npm install xe-utils vxe-tablenext 在項目main.js引入 import …

HOOPS Exchange 與HOOPS Communicator集成:打造工業3D可視化新標桿!

一、概述 在工業3D開發、BIM建筑、數字孿生和仿真分析等高端應用場景中&#xff0c;數據格式復雜、模型體量龐大、實時交互體驗要求高&#xff0c;一直是困擾開發者的難題。Tech Soft 3D旗下的HOOPS Exchange和HOOPS Communicator&#xff0c;正是解決這類問題的黃金搭檔。二者…

《軟件設計師》復習筆記(14.3)——設計模式

目錄 一、設計模式分類 1. 創建型模式&#xff08;Creational Patterns&#xff09; 2. 結構型模式&#xff08;Structural Patterns&#xff09; 3. 行為型模式&#xff08;Behavioral Patterns&#xff09; 真題示例&#xff1a; 一、設計模式分類 架構模式 高層設計決…

HarmonyOS:使用Refresh組件實現頁面下拉刷新上拉加載更多

一、前言 可以進行頁面下拉操作并顯示刷新動效的容器組件。 說明 該組件從API Version 8開始支持。后續版本如有新增內容&#xff0c;則采用上角標單獨標記該內容的起始版本。該組件從API Version 12開始支持與垂直滾動的Swiper和Web的聯動。當Swiper設置loop屬性為true時&…

55、?屏加載?屏怎么進?優化

答&#xff1a; &#xff08;1&#xff09;使?CDN 減?代碼體積&#xff0c;加快請求速度&#xff1b; (2)SSR通過服務端把所有數據全部渲染完成再返回給客?端&#xff1b; (3) 路由懶加載&#xff0c;當??訪問的時候&#xff0c;再加載相應模塊&#xff1b; (4) 使?外…

什么是Python單例模式

什么是Python單例模式 Python單例模式是一種創建型設計模式,目的是確保一個類僅有一個實例,并提供一個全局訪問點來獲取該實例。以下從作用和示例進行介紹: 作用 控制資源使用:避免對系統資源的重復消耗,像數據庫連接、文件句柄等稀缺資源,只創建一個實例來管理使用,防…

Java 2025:解鎖未來5大技術趨勢,Kotlin融合AI新篇

各位Java開發者們好&#xff01;&#x1f680; 2025年的Java世界正在經歷一場前所未有的技術變革。作為深耕Java領域多年的技術博主&#xff0c;今天我將帶大家深入探索Java生態即將迎來的5大技術趨勢&#xff0c;特別是Kotlin的深度融合和AI技術的新篇章。準備好了嗎&#xff…

計算機視覺cv2入門之車牌號碼識別

前邊我們已經講解了使用cv2進行圖像預處理與邊緣檢測等方面的知識&#xff0c;這里我們以車牌號碼識別這一案例來實操一下。 大致思路 車牌號碼識別的大致流程可以分為這三步&#xff1a;圖像預處理-尋找車牌輪廓-車牌OCR識別 接下來我們按照這三步來進行講解。 圖像預處理 …

CExercise_13_1排序算法_3快速排序算法,包括單向分區以及雙向分區

題目&#xff1a; 請手動實現快速排序算法&#xff0c;包括單向分區以及雙向分區&#xff1a; // 單向分區快速排序算法 void quick_sort_one_way(int arr[], int len); //雙向分區快速排序算法 void quick_sort_two_way(int arr[], int len); 關鍵點 分析&#xff1a; &#x…

FPGA-VGA

目錄 前言 一、VGA是什么&#xff1f; 二、物理接口 三、VGA顯示原理 四、VGA時序標準 五、VGA顯示參數 六、模塊設計 七、波形圖設計 八、彩條波形數據 前言 VGA的FPGA驅動 一、VGA是什么&#xff1f; VGA&#xff08;Video Graphics Array&#xff09;是IBM于1987年推出的…

Linux和Ubuntu的驅動適配情況

舊 一、Linux Yocto3.0 二、Ubuntu 1.驅動 1.rtc正常 2.led正常 3.加密芯片正常 4.硬件看門狗不行&#xff0c;驅動已經適配好&#xff0c;等硬件修復后&#xff0c;直接使用腳本就可以 5.千兆網口可以&#xff0c;兩個百兆網口不行 6.USB上面和下面都可以&#xff08;插u盤…

Python 文本和字節序列(處理文本文件)

本章將討論下述話題&#xff1a; 字符、碼位和字節表述 bytes、bytearray 和 memoryview 等二進制序列的獨特特性 全部 Unicode 和陳舊字符集的編解碼器 避免和處理編碼錯誤 處理文本文件的最佳實踐 默認編碼的陷阱和標準 I/O 的問題 規范化 Unicode 文本&#xff0c;進行安全的…