String 类

定义

将文本表示为 UTF-16 代码单元的序列。

public ref class System::String sealed : IComparable, IComparable<System::String ^>, IConvertible, IEquatable<System::String ^>, System::Collections::Generic::IEnumerable<char>
public ref class System::String sealed : ICloneable, IComparable, IComparable<System::String ^>, IConvertible, IEquatable<System::String ^>, System::Collections::Generic::IEnumerable<char>
public ref class System::String sealed : ICloneable, IComparable, IConvertible, System::Collections::IEnumerable
public ref class System::String sealed : IComparable, IComparable<System::String ^>, IEquatable<System::String ^>, System::Collections::IEnumerable
public ref class System::String sealed : IComparable, IComparable<System::String ^>, IEquatable<System::String ^>, System::Collections::Generic::IEnumerable<char>
public sealed class String : IComparable, IComparable<string>, IConvertible, IEquatable<string>, System.Collections.Generic.IEnumerable<char>
public sealed class String : ICloneable, IComparable, IComparable<string>, IConvertible, IEquatable<string>, System.Collections.Generic.IEnumerable<char>
[System.Serializable]
public sealed class String : ICloneable, IComparable, IConvertible, System.Collections.IEnumerable
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class String : ICloneable, IComparable, IComparable<string>, IConvertible, IEquatable<string>, System.Collections.Generic.IEnumerable<char>
public sealed class String : IComparable, IComparable<string>, IEquatable<string>, System.Collections.IEnumerable
public sealed class String : IComparable, IComparable<string>, IEquatable<string>, System.Collections.Generic.IEnumerable<char>
type string = class
    interface seq<char>
    interface IEnumerable
    interface IComparable
    interface IComparable<string>
    interface IConvertible
    interface IEquatable<string>
type string = class
    interface seq<char>
    interface IEnumerable
    interface ICloneable
    interface IComparable
    interface IComparable<string>
    interface IConvertible
    interface IEquatable<string>
type string = class
    interface seq<char>
    interface IEnumerable
    interface IComparable
    interface IComparable<string>
    interface IConvertible
    interface IEquatable<string>
    interface ICloneable
[<System.Serializable>]
type string = class
    interface IComparable
    interface ICloneable
    interface IConvertible
    interface IEnumerable
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type string = class
    interface IComparable
    interface ICloneable
    interface IConvertible
    interface IComparable<string>
    interface seq<char>
    interface IEnumerable
    interface IEquatable<string>
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type string = class
    interface IComparable
    interface ICloneable
    interface IConvertible
    interface IEnumerable
    interface IComparable<string>
    interface seq<char>
    interface IEquatable<string>
type string = class
    interface IEnumerable
    interface IComparable
    interface IComparable<string>
    interface IEquatable<string>
type string = class
    interface IComparable
    interface IComparable<string>
    interface IEquatable<string>
    interface seq<char>
    interface IEnumerable
Public NotInheritable Class String
Implements IComparable, IComparable(Of String), IConvertible, IEnumerable(Of Char), IEquatable(Of String)
Public NotInheritable Class String
Implements ICloneable, IComparable, IComparable(Of String), IConvertible, IEnumerable(Of Char), IEquatable(Of String)
Public NotInheritable Class String
Implements ICloneable, IComparable, IConvertible, IEnumerable
Public NotInheritable Class String
Implements IComparable, IComparable(Of String), IEnumerable, IEquatable(Of String)
Public NotInheritable Class String
Implements IComparable, IComparable(Of String), IEnumerable(Of Char), IEquatable(Of String)
继承
String
属性
实现

注解

字符串是用于表示文本的字符的顺序集合。 对象 String 是表示字符串的对象的顺序集合 System.Char ;对象 System.Char 对应于 UTF-16 代码单元。 对象的值 String 是对象顺序集合 System.Char 的内容,该值不可变 (即只读) 。 有关字符串不可变性的详细信息,请参阅 Immutability 和 StringBuilder 类 部分。 内存中对象的最大大小 String 为 2-GB,或大约 10 亿个字符。

有关 Unicode、UTF-16、代码单元、代码点和CharRune类型的详细信息,请参阅 .NET 中的字符编码简介

本节内容:

实例化 String 对象
Char 对象和 Unicode 字符
字符串和 Unicode 标准
字符串和嵌入的 null 字符
字符串和索引
Null 字符串和空字符串
不可变性和 StringBuilder 类
序号与区域性敏感操作
规范化
按类别划分的字符串操作

实例化 String 对象

可以通过以下方式实例化 String 对象:

  • 通过将字符串文本分配给 String 变量。 这是用于创建字符串的最常用方法。 以下示例使用赋值创建多个字符串。 请注意,在 C# 和 F# 中,由于反斜杠 (\) 是转义字符,因此字符串中的文本反斜杠必须转义或整个字符串必须 @-quoted转义。

    using namespace System;
    
    void main()
    {
       String^ string1 = "This is a string created by assignment.";
       Console::WriteLine(string1);
       String^ string2a = "The path is C:\\PublicDocuments\\Report1.doc";
       Console::WriteLine(string2a);
    }
    // The example displays the following output: 
    //       This is a string created by assignment. 
    //       The path is C:\PublicDocuments\Report1.doc
    
    string string1 = "This is a string created by assignment.";
    Console.WriteLine(string1);
    string string2a = "The path is C:\\PublicDocuments\\Report1.doc";
    Console.WriteLine(string2a);
    string string2b = @"The path is C:\PublicDocuments\Report1.doc";
    Console.WriteLine(string2b);
    // The example displays the following output:
    //       This is a string created by assignment.
    //       The path is C:\PublicDocuments\Report1.doc
    //       The path is C:\PublicDocuments\Report1.doc
    
    let string1 = "This is a string created by assignment."
    printfn "%s" string1
    let string2a = "The path is C:\\PublicDocuments\\Report1.doc"
    printfn "%s" string2a
    let string2b = @"The path is C:\PublicDocuments\Report1.doc"
    printfn "%s" string2b
    // The example displays the following output:
    //       This is a string created by assignment.
    //       The path is C:\PublicDocuments\Report1.doc
    //       The path is C:\PublicDocuments\Report1.doc
    
    Dim string1 As String = "This is a string created by assignment."
    Console.WriteLine(string1)
    Dim string2 As String = "The path is C:\PublicDocuments\Report1.doc"
    Console.WriteLine(string2)
    ' The example displays the following output:
    '       This is a string created by assignment.
    '       The path is C:\PublicDocuments\Report1.doc
    
  • 通过调用 String 类构造函数。 以下示例通过调用多个类构造函数实例化字符串。 请注意,某些构造函数包括指向字符数组或带符号字节数组的指针作为参数。 Visual Basic不支持对这些构造函数的调用。 有关构造函数的详细信息 String ,请参阅 String 构造函数摘要。

    using namespace System;
    
    void main()
    {
       wchar_t chars[5] = L"word";
       char bytes[6] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 };
    
       // Create a string from a character array. 
       String^ string1 = gcnew String(chars);
       Console::WriteLine(string1);
    
       // Create a string that consists of a character repeated 20 times. 
       String^ string2 = gcnew String('c', 20);
       Console::WriteLine(string2);
    
       String^ stringFromBytes = nullptr;
       String^ stringFromChars = nullptr;
    
       char * pbytes = &bytes[0];
       // Create a string from a pointer to a signed byte array.
       stringFromBytes = gcnew String(pbytes);
    
       wchar_t* pchars =  &chars[0];
       // Create a string from a pointer to a character array.
       stringFromChars = gcnew String(pchars);
    
       Console::WriteLine(stringFromBytes);
       Console::WriteLine(stringFromChars);
       Console::ReadLine();
    }
    // The example displays the following output: 
    //       word 
    //       cccccccccccccccccccc 
    //       ABCDE 
    //       word
    
    char[] chars = { 'w', 'o', 'r', 'd' };
    sbyte[] bytes = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 };
    
    // Create a string from a character array.
    string string1 = new string(chars);
    Console.WriteLine(string1);
    
    // Create a string that consists of a character repeated 20 times.
    string string2 = new string('c', 20);
    Console.WriteLine(string2);
    
    string stringFromBytes = null;
    string stringFromChars = null;
    unsafe
    {
       fixed (sbyte* pbytes = bytes)
       {
          // Create a string from a pointer to a signed byte array.
          stringFromBytes = new string(pbytes);
       }
       fixed (char* pchars = chars)
       {
          // Create a string from a pointer to a character array.
          stringFromChars = new string(pchars);
       }
    }
    Console.WriteLine(stringFromBytes);
    Console.WriteLine(stringFromChars);
    // The example displays the following output:
    //       word
    //       cccccccccccccccccccc
    //       ABCDE
    //       word
    
    let chars = [| 'w'; 'o'; 'r'; 'd' |]
    let bytes = [| 0x41y; 0x42y; 0x43y; 0x44y; 0x45y; 0x00y |]
    
    // Create a string from a character array.
    let string1 = String chars
    printfn "%s" string1
    
    // Create a string that consists of a character repeated 20 times.
    let string2 = String('c', 20)
    printfn "%s" string2
    
    let stringFromBytes =
        // Create a string from a pointer to a signed byte array.
        use pbytes = fixed bytes
        String pbytes
    let stringFromChars = 
        // Create a string from a pointer to a character array.
        use pchars = fixed chars
        String pchars
    
    printfn $"{stringFromBytes}"
    printfn $"{stringFromChars}"
    // The example displays the following output:
    //       word
    //       cccccccccccccccccccc
    //       ABCDE
    //       word
    
    Dim chars() As Char = { "w"c, "o"c, "r"c, "d"c }
    
    ' Create a string from a character array.
    Dim string1 As New String(chars)
    Console.WriteLine(string1)
    
    ' Create a string that consists of a character repeated 20 times.
    Dim string2 As New String("c"c, 20)
    Console.WriteLine(string2)
    ' The example displays the following output:
    '       word
    '       cccccccccccccccccccc
    
  • 通过在 C# 和 F# 中使用字符串串联运算符 (+,并在 Visual Basic) 中使用 & 或 + 来创建单个字符串,以从实例和字符串文本的任何组合String创建一个字符串。 以下示例演示了字符串串联运算符的使用。

    String^ string1 = "Today is " + DateTime::Now.ToString("D") + ".";
    Console::WriteLine(string1);
    
    String^ string2 = "This is one sentence. " + "This is a second. ";
    string2 += "This is a third sentence.";
    Console::WriteLine(string2);
    // The example displays output like the following: 
    //    Today is Tuesday, July 06, 2011. 
    //    This is one sentence. This is a second. This is a third sentence.
    
    string string1 = "Today is " + DateTime.Now.ToString("D") + ".";
    Console.WriteLine(string1);
    
    string string2 = "This is one sentence. " + "This is a second. ";
    string2 += "This is a third sentence.";
    Console.WriteLine(string2);
    // The example displays output like the following:
    //    Today is Tuesday, July 06, 2011.
    //    This is one sentence. This is a second. This is a third sentence.
    
    let string1 = "Today is " + DateTime.Now.ToString("D") + "."
    printfn $"{string1}"
    
    let string2 = "This is one sentence. " + "This is a second. "
    let string2 = string2 + "This is a third sentence."
    printfn $"{string2}"
    // The example displays output like the following:
    //    Today is Tuesday, July 06, 2011.
    //    This is one sentence. This is a second. This is a third sentence.
    
    Dim string1 As String = "Today is " + Date.Now.ToString("D") + "."  
    Console.WriteLine(string1)
    Dim string2 As String = "This is one sentence. " + "This is a second. "
    string2 += "This is a third sentence."
    Console.WriteLine(string2)      
    ' The example displays output like the following:
    '    Today is Tuesday, July 06, 2011.
    '    This is one sentence. This is a second. This is a third sentence.
    
  • 通过检索属性或调用返回字符串的方法。 以下示例使用类的方法 String 从较大的字符串中提取子字符串。

    String^ sentence = "This sentence has five words.";
    // Extract the second word.
    int startPosition = sentence->IndexOf(" ") + 1;
    String^ word2 = sentence->Substring(startPosition, 
                                        sentence->IndexOf(" ", startPosition) - startPosition);
    Console::WriteLine("Second word: " + word2);
    
    string sentence = "This sentence has five words.";
    // Extract the second word.
    int startPosition = sentence.IndexOf(" ") + 1;
    string word2 = sentence.Substring(startPosition,
                                      sentence.IndexOf(" ", startPosition) - startPosition);
    Console.WriteLine("Second word: " + word2);
    // The example displays the following output:
    //       Second word: sentence
    
    let sentence = "This sentence has five words."
    // Extract the second word.
    let startPosition = sentence.IndexOf " " + 1
    let word2 = 
        sentence.Substring(startPosition, sentence.IndexOf(" ", startPosition) - startPosition)
    printfn $"Second word: {word2}"
    // The example displays the following output:
    //       Second word: sentence
    
    Dim sentence As String = "This sentence has five words."
    ' Extract the second word.
    Dim startPosition As Integer = sentence.IndexOf(" ") + 1
    Dim word2 As String = sentence.Substring(startPosition, 
                                             sentence.IndexOf(" ", startPosition) - startPosition) 
    Console.WriteLine("Second word: " + word2)
    ' The example displays the following output:
    '       Second word: sentence
    
  • 通过调用格式设置方法将值或对象转换为其字符串表示形式。 以下示例使用 复合格式 设置功能将两个对象的字符串表示形式嵌入字符串中。

    DateTime^ dateAndTime = gcnew DateTime(2011, 7, 6, 7, 32, 0);
    Double temperature = 68.3;
    String^ result = String::Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.",
                                   dateAndTime, temperature);
    Console::WriteLine(result);
    // The example displays the following output: 
    //       At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.
    
    DateTime dateAndTime = new DateTime(2011, 7, 6, 7, 32, 0);
    double temperature = 68.3;
    string result = String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.",
                                  dateAndTime, temperature);
    Console.WriteLine(result);
    // The example displays the following output:
    //       At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.
    
    let dateAndTime = DateTime(2011, 7, 6, 7, 32, 0)
    let temperature = 68.3
    String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.", dateAndTime, temperature)
    |> printfn "%s"
    // The example displays the following output:
    //       At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.
    
    Dim dateAndTime As DateTime = #07/06/2011 7:32:00AM#
    Dim temperature As Double = 68.3
    Dim result As String = String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.",
                                         dateAndTime, temperature)
    Console.WriteLine(result)
    ' The example displays the following output:
    '       At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.
    

Char 对象和 Unicode 字符

字符串中的每个字符都由 Unicode 标量值定义,也称为 Unicode 代码点或 Unicode 字符的序号 (数值) 值。 每个代码点都使用 UTF-16 编码进行编码,编码的每个元素的数值由对象 Char 表示。

备注

请注意,由于 String 实例由 UTF-16 代码单元的顺序集合组成,因此可以创建一个 String 格式不正确 Unicode 字符串的对象。 例如,可以创建具有低代理项且没有相应高代理项的字符串。 尽管某些方法(如命名空间中的 System.Text 编码和解码对象的方法)可能会执行检查,以确保字符串格式良好, String 类成员不会确保字符串格式正确。

单个 Char 对象通常表示单个代码点;也就是说,代码点的 Char 数值等于代码点。 例如,字符“a”的代码点为 U+0061。 但是,代码点可能需要多个编码元素 (多个 Char 对象) 。 Unicode 标准定义了两种类型的字符,这些字符对应于多个 Char 对象:图形和 Unicode 补充代码点,这些代码点对应于 Unicode 补充平面中的字符。

  • grapheme 由基字符表示,后跟一个或多个组合字符。 例如,字符 ä 由 Char 代码点为 U+0061 的对象表示,后跟 Char 代码点为 U+0308 的对象。 此字符也可以由具有 U+00E4 代码点的单个 Char 对象定义。 如以下示例所示,区分区域性的相等比较表明这两个表示形式相等,尽管普通序号比较不相等。 但是,如果两个字符串规范化,序号比较也表示它们相等。 (有关规范化字符串的详细信息,请参阅 “规范化 ”部分。)

    using namespace System;
    using namespace System::Globalization;
    using namespace System::IO;
    
    void main()
    {
       StreamWriter^ sw = gcnew StreamWriter(".\\graphemes.txt");
       String^ grapheme = L"a" + L"\u0308";
       sw->WriteLine(grapheme);
    
       String^ singleChar = "\u00e4";
       sw->WriteLine(singleChar);
    
       sw->WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, 
                      String::Equals(grapheme, singleChar, 
                                  StringComparison::CurrentCulture));
       sw->WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar, 
                      String::Equals(grapheme, singleChar, 
                                  StringComparison::Ordinal));
       sw->WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar, 
                      String::Equals(grapheme->Normalize(), 
                                  singleChar->Normalize(), 
                                  StringComparison::Ordinal));
       sw->Close(); 
    }
    // The example produces the following output: 
    //       ä 
    //       ä 
    //       ä = ä (Culture-sensitive): True 
    //       ä = ä (Ordinal): False 
    //       ä = ä (Normalized Ordinal): True
    
    using System;
    using System.Globalization;
    using System.IO;
    
    public class Example
    {
       public static void Main()
       {
          StreamWriter sw = new StreamWriter(@".\graphemes.txt");
          string grapheme = "\u0061\u0308";
          sw.WriteLine(grapheme);
          
          string singleChar = "\u00e4";
          sw.WriteLine(singleChar);
                
          sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, 
                       String.Equals(grapheme, singleChar, 
                                     StringComparison.CurrentCulture));
          sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar, 
                       String.Equals(grapheme, singleChar, 
                                     StringComparison.Ordinal));
          sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar, 
                       String.Equals(grapheme.Normalize(), 
                                     singleChar.Normalize(), 
                                     StringComparison.Ordinal));
          sw.Close(); 
       }
    }
    // The example produces the following output:
    //       ä
    //       ä
    //       ä = ä (Culture-sensitive): True
    //       ä = ä (Ordinal): False
    //       ä = ä (Normalized Ordinal): True
    
    open System
    open System.IO
    
    do
        use sw = new StreamWriter(@".\graphemes.txt")
        let grapheme = "\u0061\u0308"
        sw.WriteLine grapheme
    
        let singleChar = "\u00e4"
        sw.WriteLine singleChar
    
        sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, 
                    String.Equals(grapheme, singleChar,
                                    StringComparison.CurrentCulture))
        sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar,
                    String.Equals(grapheme, singleChar,
                                    StringComparison.Ordinal))
        sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar,
                    String.Equals(grapheme.Normalize(),
                                    singleChar.Normalize(),
                                    StringComparison.Ordinal))
    // The example produces the following output:
    //       ä
    //       ä
    //       ä = ä (Culture-sensitive): True
    //       ä = ä (Ordinal): False
    //       ä = ä (Normalized Ordinal): True
    
    Imports System.Globalization
    Imports System.IO
    
    Module Example
       Public Sub Main()
          Dim sw As New StreamWriter(".\graphemes.txt")
          Dim grapheme As String = ChrW(&H0061) + ChrW(&h0308)
          sw.WriteLine(grapheme)
          
          Dim singleChar As String = ChrW(&h00e4)
          sw.WriteLine(singleChar)
                
          sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar, 
                       String.Equals(grapheme, singleChar, 
                                     StringComparison.CurrentCulture))
          sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar, 
                       String.Equals(grapheme, singleChar, 
                                     StringComparison.Ordinal))
          sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar, 
                       String.Equals(grapheme.Normalize(), 
                                     singleChar.Normalize(), 
                                     StringComparison.Ordinal))
          sw.Close() 
       End Sub
    End Module
    ' The example produces the following output:
    '       ä
    '       ä
    '       ä = ä (Culture-sensitive): True
    '       ä = ä (Ordinal): False
    '       ä = ä (Normalized Ordinal): True
    
  • (代理项配对) 的 Unicode 补充代码点由代码点为高代理项的对象表示Char,后跟Char代码点为低代理项的对象。 高代理项的代码单元范围从 U+D800 到 U+DBFF。 低代理项的代码单元范围从 U+DC00 到 U+DFFF。 代理项对用于表示 16 个 Unicode 补充平面中的字符。 以下示例创建代理项字符并将其传递给Char.IsSurrogatePair(Char, Char)方法,以确定它是代理项配对。

    using namespace System;
    
    void main()
    {
       String^ surrogate =  L"\xD800\xDC03" ;
       for (int ctr = 0; ctr < surrogate->Length; ctr++)
          Console::Write("U+{0:X4} ", Convert::ToUInt16(surrogate[ctr]));
    
       Console::WriteLine();
       Console::WriteLine("   Is Surrogate Pair: {0}", 
                          Char::IsSurrogatePair(surrogate[0], surrogate[1]));
       Console::ReadLine();
    }
    // The example displays the following output: 
    //       U+D800 U+DC03 
    //          Is Surrogate Pair: True
    
    string surrogate = "\uD800\uDC03";
    for (int ctr = 0; ctr < surrogate.Length; ctr++) 
       Console.Write($"U+{(ushort)surrogate[ctr]:X2} ");
    
    Console.WriteLine();
    Console.WriteLine("   Is Surrogate Pair: {0}", 
                      Char.IsSurrogatePair(surrogate[0], surrogate[1]));
    // The example displays the following output:
    //       U+D800 U+DC03
    //          Is Surrogate Pair: True
    
    open System
    
    let surrogate = "\uD800\uDC03"
    for i = 0 to surrogate.Length - 1 do
        printf $"U+{uint16 surrogate[i]:X2} "
    
    printfn $"\n   Is Surrogate Pair: {Char.IsSurrogatePair(surrogate[0], surrogate[1])}"
    // The example displays the following output:
    //       U+D800 U+DC03
    //          Is Surrogate Pair: True
    
    Module Example
       Public Sub Main()
          Dim surrogate As String = ChrW(&hD800) + ChrW(&hDC03)
          For ctr As Integer = 0 To surrogate.Length - 1
             Console.Write("U+{0:X2} ", Convert.ToUInt16(surrogate(ctr)))
          Next   
          Console.WriteLine()
          Console.WriteLine("   Is Surrogate Pair: {0}", 
                            Char.IsSurrogatePair(surrogate(0), surrogate(1)))
       End Sub
    End Module
    
    ' The example displays the following output:
    '       U+D800 U+DC03
    '          Is Surrogate Pair: True
    

字符串和 Unicode 标准

字符串中的字符由 UTF-16 编码的代码单元表示,这些单元对应于 Char 值。

字符串中的每个字符都有关联的 Unicode 字符类别,该类别由 UnicodeCategory 枚举在 .NET 中表示。 可以通过调用CharUnicodeInfo.GetUnicodeCategory方法来确定字符或代理项配对的类别。

.NET 维护自己的字符表及其相应的类别,这可确保在不同平台上运行的特定版本的 .NET 实现返回相同的字符类别信息。 在所有 .NET 版本和所有 OS 平台上,字符类别信息由 Unicode 字符数据库提供。

下表列出了 .NET 版本及其字符类别所基于的 Unicode 标准。

.NET 版本 Unicode 标准版本
.NET Framework 1.1 Unicode 标准,版本 4.0.0
.NET Framework 2.0 Unicode 标准,版本 5.0.0
.NET Framework 3.5 Unicode 标准,版本 5.0.0
.NET Framework 4 Unicode 标准,版本 5.0.0
.NET Framework 4.5 Unicode 标准,版本 6.3.0
.NET Framework 4.5.1 Unicode 标准,版本 6.3.0
.NET Framework 4.5.2 Unicode 标准,版本 6.3.0
.NET Framework 4.6 Unicode 标准,版本 6.3.0
.NET Framework 4.6.1 Unicode 标准,版本 6.3.0
.NET Framework 4.6.2 及更高版本 Unicode 标准,版本 8.0.0
.NET Core 2.1 Unicode 标准,版本 8.0.0
.NET Core 3.1 Unicode 标准11.0.0 版
.NET 5 Unicode 标准版本13.0。0

此外,.NET 还支持基于 Unicode 标准进行字符串比较和排序。 .NET Framework 4 和早期版本维护其自己的字符串数据表。 从 Windows 7 上运行的 .NET Framework 4.5 开始,这也是.NET Framework的版本。 从Windows 8和更高版本的 Windows 操作系统上运行的 .NET Framework 4.5 开始,运行时会将字符串比较和排序操作委托给操作系统。 在 .NET Core 和 .NET 5+上,Unicode 库的国际组件提供了字符串比较和排序信息 (,但Windows 10 2019 年 5 月更新) 之前的Windows版本除外。 下表列出了 .NET 的版本和 Unicode 标准版本,其中基于字符比较和排序。

.NET 版本 Unicode 标准版本
.NET Framework 1.1 Unicode 标准,版本 4.0.0
.NET Framework 2.0 Unicode 标准,版本 5.0.0
.NET Framework 3.5 Unicode 标准,版本 5.0.0
.NET Framework 4 Unicode 标准,版本 5.0.0
Windows 7 上的 .NET Framework 4.5 及更高版本 Unicode 标准,版本 5.0.0
.NET Framework 4.5 及更高版本Windows 8及更高版本Windows操作系统 Unicode 标准,版本 6.3.0
.NET Core 和 .NET 5+ 取决于基础操作系统支持的 Unicode 标准版本。

字符串和嵌入的 null 字符

在 .NET 中, String 对象可以包含嵌入的 null 字符,这些字符计数为字符串长度的一部分。 但是,在某些语言(如 C 和 C++)中,null 字符指示字符串的末尾;它不被视为字符串的一部分,不会计入字符串长度的一部分。 这意味着在应用于 String 对象时,C 和 C++ 程序员或 C++ 编写的 C 和 C++ 程序员或库可能对字符串进行以下常见假设不一定有效:

  • strlen``wcslen函数返回的值不一定相等String.Length

  • strcpy_swcscpy_s 函数创建的字符串不一定与方法创建的 String.Copy 字符串相同。

应确保实例化 String 对象的本机 C 和 C++ 代码,以及通过平台调用传递 String 对象的代码,不要假定嵌入的 null 字符标记字符串的末尾。

字符串中嵌入的 null 字符在对字符串进行排序 (或比较) 时以及搜索字符串时也不同。 在两个字符串之间执行区分区域性的比较时,将忽略 Null 字符,包括使用固定区域性的比较。 它们仅用于序号或不区分大小写的序号比较。 另一方面,使用方法(例如 ContainsStartsWithIndexOf)搜索字符串时,始终考虑嵌入的 null 字符。

字符串和索引

索引是对象的位置Char, (不是 Unicode 字符) 。String 索引是从字符串的第一个位置开始的从零开始的非负数,即索引位置为零。 许多搜索方法(例如 IndexOf ,以及 LastIndexOf)在字符串实例中返回字符或子字符串的索引。

Chars[] 属性允许你通过字符串中的索引位置访问各个 Char 对象。 由于该Chars[]属性是 Visual Basic) 中的默认属性 (,或者 C# 和 F# ) 中的索引器 (,因此可以使用如下代码访问字符串中的单个Char对象。 此代码查找字符串中的空格或标点符号字符,以确定字符串包含的单词数。

using namespace System;

void main()
{
   String^ s1 = "This string consists of a single short sentence.";
   int nWords = 0;

   s1 = s1->Trim();      
   for (int ctr = 0; ctr < s1->Length; ctr++) {
         if (Char::IsPunctuation(s1[ctr]) | Char::IsWhiteSpace(s1[ctr]))
            nWords++;              
   }
   Console::WriteLine("The sentence\n   {0}\nhas {1} words.",
                     s1, nWords);           
}
// The example displays the following output: 
//       The sentence 
//          This string consists of a single short sentence. 
//       has 8 words.
string s1 = "This string consists of a single short sentence.";
int nWords = 0;

s1 = s1.Trim();      
for (int ctr = 0; ctr < s1.Length; ctr++) {
   if (Char.IsPunctuation(s1[ctr]) | Char.IsWhiteSpace(s1[ctr]))
      nWords++;              
}
Console.WriteLine("The sentence\n   {0}\nhas {1} words.",
                  s1, nWords);                                                                     
// The example displays the following output:
//       The sentence
//          This string consists of a single short sentence.
//       has 8 words.
let s1 = "This string consists of a single short sentence."
let mutable nWords = 0

for i = 0 to s1.Length - 1 do
    if Char.IsPunctuation s1[i] || Char.IsWhiteSpace s1[i] then
        nWords <- nWords + 1
printfn $"The sentence\n   {s1}\nhas {nWords} words."
// The example displays the following output:
//       The sentence
//          This string consists of a single short sentence.
//       has 8 words.
Module Example
   Public Sub Main()
      Dim s1 As String = "This string consists of a single short sentence."
      Dim nWords As Integer = 0

      s1 = s1.Trim()      
      For ctr As Integer = 0 To s1.Length - 1
         If Char.IsPunctuation(s1(ctr)) Or Char.IsWhiteSpace(s1(ctr)) 
            nWords += 1              
         End If   
      Next
      Console.WriteLine("The sentence{2}   {0}{2}has {1} words.",
                        s1, nWords, vbCrLf)                                                                     
   End Sub
End Module
' The example displays the following output:
'       The sentence
'          This string consists of a single short sentence.
'       has 8 words.

由于类String实现IEnumerable接口,因此还可以使用foreach构造循环访问Char字符串中的对象,如以下示例所示。

using namespace System;

void main()
{
   String^ s1 = "This string consists of a single short sentence.";
   int nWords = 0;

   s1 = s1->Trim();      
   for each (Char ch in s1)
   {
      if (Char::IsPunctuation(ch) | Char::IsWhiteSpace(ch))
         nWords++;              
   }
   Console::WriteLine("The sentence\n   {0}\nhas {1} words.",
                      s1, nWords);  
   Console::ReadLine();
}
// The example displays the following output: 
//       The sentence 
//          This string consists of a single short sentence. 
//       has 8 words.
string s1 = "This string consists of a single short sentence.";
int nWords = 0;

s1 = s1.Trim();      
foreach (var ch in s1) {
   if (Char.IsPunctuation(ch) | Char.IsWhiteSpace(ch))
      nWords++;              
}
Console.WriteLine("The sentence\n   {0}\nhas {1} words.",
                  s1, nWords);                                                                     
// The example displays the following output:
//       The sentence
//          This string consists of a single short sentence.
//       has 8 words.
let s1 = "This string consists of a single short sentence."
let mutable nWords = 0

for ch in s1 do
    if Char.IsPunctuation ch || Char.IsWhiteSpace ch then
        nWords <- nWords + 1
printfn $"The sentence\n   {s1}\nhas {nWords} words."
// The example displays the following output:
//       The sentence
//          This string consists of a single short sentence.
//       has 8 words.
Module Example
   Public Sub Main()
      Dim s1 As String = "This string consists of a single short sentence."
      Dim nWords As Integer = 0

      s1 = s1.Trim()      
      For Each ch In s1
         If Char.IsPunctuation(ch) Or Char.IsWhiteSpace(ch) Then 
            nWords += 1              
         End If   
      Next
      Console.WriteLine("The sentence{2}   {0}{2}has {1} words.",
                        s1, nWords, vbCrLf)                                                                     
   End Sub
End Module
' The example displays the following output:
'       The sentence
'          This string consists of a single short sentence.
'       has 8 words.

连续索引值可能与连续 Unicode 字符不对应,因为 Unicode 字符可能编码为多个 Char 对象。 具体而言,字符串可能包含由基字符后跟一个或多个组合字符或代理项对构成的文本的多字符单位。 若要使用 Unicode 字符而不是 Char 对象,请使用 System.Globalization.StringInfoTextElementEnumerator 类,或者 String.EnumerateRunes 使用方法和 Rune 结构。 下面的示例演示了与对象和 Char 使用 Unicode 字符的代码之间的差异。 它比较句子的每个单词中的字符数或文本元素数。 该字符串包含两个基字符序列,后跟组合字符。

using namespace System;
using namespace System::Collections::Generic;
using namespace System::Globalization;

void main()
{
   // First sentence of The Mystery of the Yellow Room, by Leroux. 
   String^ opening = L"Ce n'est pas sans une certaine émotion que "+
                     L"je commence à raconter ici les aventures " +
                     L"extraordinaires de Joseph Rouletabille."; 
  
   // Character counters. 
   int nChars = 0;
   // Objects to store word count.
   List<int>^ chars = gcnew List<int>();
   List<int>^ elements = gcnew List<int>();

   for each (Char ch in opening) {
      // Skip the ' character. 
      if (ch == '\x0027') continue;

      if (Char::IsWhiteSpace(ch) | (Char::IsPunctuation(ch))) {
         chars->Add(nChars);
         nChars = 0;
      }
      else {
         nChars++;
      }
   }

   TextElementEnumerator^ te = StringInfo::GetTextElementEnumerator(opening);
   while (te->MoveNext()) {
      String^ s = te->GetTextElement();   
      // Skip the ' character. 
      if (s == "\x0027") continue;
      if ( String::IsNullOrEmpty(s->Trim()) | (s->Length == 1 && Char::IsPunctuation(Convert::ToChar(s)))) {
         elements->Add(nChars);         
         nChars = 0;
      }
      else {
         nChars++;
      }
   }

   // Display character counts.
   Console::WriteLine("{0,6} {1,20} {2,20}",
                      "Word #", "Char Objects", "Characters"); 
   for (int ctr = 0; ctr < chars->Count; ctr++) 
      Console::WriteLine("{0,6} {1,20} {2,20}",
                         ctr, chars[ctr], elements[ctr]); 
   Console::ReadLine();
}
// The example displays the following output:
//      Word #         Char Objects           Characters
//           0                    2                    2
//           1                    4                    4
//           2                    3                    3
//           3                    4                    4
//           4                    3                    3
//           5                    8                    8
//           6                    8                    7
//           7                    3                    3
//           8                    2                    2
//           9                    8                    8
//          10                    2                    1
//          11                    8                    8
//          12                    3                    3
//          13                    3                    3
//          14                    9                    9
//          15                   15                   15
//          16                    2                    2
//          17                    6                    6
//          18                   12                   12
// First sentence of The Mystery of the Yellow Room, by Leroux.
string opening = "Ce n'est pas sans une certaine émotion que "+
                 "je commence à raconter ici les aventures " +
                 "extraordinaires de Joseph Rouletabille."; 
// Character counters.
int nChars = 0;
// Objects to store word count.
List<int> chars = new List<int>();
List<int> elements = new List<int>();

foreach (var ch in opening) {
   // Skip the ' character.
   if (ch == '\u0027') continue;
        
   if (Char.IsWhiteSpace(ch) | (Char.IsPunctuation(ch))) {
      chars.Add(nChars);
      nChars = 0;
   }
   else {
      nChars++;
   }
}

System.Globalization.TextElementEnumerator te = 
   System.Globalization.StringInfo.GetTextElementEnumerator(opening);
while (te.MoveNext()) {
   string s = te.GetTextElement();   
   // Skip the ' character.
   if (s == "\u0027") continue;
   if ( String.IsNullOrEmpty(s.Trim()) | (s.Length == 1 && Char.IsPunctuation(Convert.ToChar(s)))) {
      elements.Add(nChars);         
      nChars = 0;
   }
   else {
      nChars++;
   }
}

// Display character counts.
Console.WriteLine("{0,6} {1,20} {2,20}",
                  "Word #", "Char Objects", "Characters"); 
for (int ctr = 0; ctr < chars.Count; ctr++) 
   Console.WriteLine("{0,6} {1,20} {2,20}",
                     ctr, chars[ctr], elements[ctr]); 
// The example displays the following output:
//       Word #         Char Objects           Characters
//            0                    2                    2
//            1                    4                    4
//            2                    3                    3
//            3                    4                    4
//            4                    3                    3
//            5                    8                    8
//            6                    8                    7
//            7                    3                    3
//            8                    2                    2
//            9                    8                    8
//           10                    2                    1
//           11                    8                    8
//           12                    3                    3
//           13                    3                    3
//           14                    9                    9
//           15                   15                   15
//           16                    2                    2
//           17                    6                    6
//           18                   12                   12
open System
open System.Globalization

// First sentence of The Mystery of the Yellow Room, by Leroux.
let opening = "Ce n'est pas sans une certaine émotion que je commence à raconter ici les aventures extraordinaires de Joseph Rouletabille."
// Character counters.
let mutable nChars = 0
// Objects to store word count.
let chars = ResizeArray<int>()
let elements = ResizeArray<int>()

for ch in opening do
    // Skip the ' character.
    if ch <> '\u0027' then
        if Char.IsWhiteSpace ch || Char.IsPunctuation ch then
            chars.Add nChars
            nChars <- 0
        else
            nChars <- nChars + 1

let te = StringInfo.GetTextElementEnumerator opening
while te.MoveNext() do
    let s = te.GetTextElement()
    // Skip the ' character.
    if s <> "\u0027" then
        if String.IsNullOrEmpty(s.Trim()) || (s.Length = 1 && Char.IsPunctuation(Convert.ToChar s)) then
            elements.Add nChars
            nChars <- 0
        else
            nChars <- nChars + 1

// Display character counts.
printfn "%6s %20s %20s" "Word #" "Char Objects " "Characters"
for i = 0 to chars.Count - 1 do
    printfn "%6d %20d %20d" i chars[i] elements[i]
// The example displays the following output:
//       Word #         Char Objects           Characters
//            0                    2                    2
//            1                    4                    4
//            2                    3                    3
//            3                    4                    4
//            4                    3                    3
//            5                    8                    8
//            6                    8                    7
//            7                    3                    3
//            8                    2                    2
//            9                    8                    8
//           10                    2                    1
//           11                    8                    8
//           12                    3                    3
//           13                    3                    3
//           14                    9                    9
//           15                   15                   15
//           16                    2                    2
//           17                    6                    6
//           18                   12                   12
Imports System.Collections.Generic
Imports System.Globalization

Module Example
   Public Sub Main()
      ' First sentence of The Mystery of the Yellow Room, by Leroux.
      Dim opening As String = "Ce n'est pas sans une certaine émotion que "+
                              "je commence à raconter ici les aventures " +
                              "extraordinaires de Joseph Rouletabille." 
      ' Character counters.
      Dim nChars As Integer = 0
      ' Objects to store word count.
      Dim chars As New List(Of Integer)()
      Dim elements As New List(Of Integer)()
      
      For Each ch In opening
         ' Skip the ' character.
         If ch = ChrW(&h0027) Then Continue For
              
         If Char.IsWhiteSpace(ch) Or Char.IsPunctuation(ch) Then
            chars.Add(nChars)
            nChars = 0
         Else 
            nChars += 1
         End If
      Next

      Dim te As TextElementEnumerator = StringInfo.GetTextElementEnumerator(opening)
      Do While te.MoveNext()
         Dim s As String = te.GetTextElement()   
         ' Skip the ' character.
         If s = ChrW(&h0027) Then Continue Do
         If String.IsNullOrEmpty(s.Trim()) Or (s.Length = 1 AndAlso Char.IsPunctuation(Convert.ToChar(s))) 
            elements.Add(nChars)         
            nChars = 0
         Else 
            nChars += 1
         End If
      Loop

      ' Display character counts.
      Console.WriteLine("{0,6} {1,20} {2,20}",
                        "Word #", "Char Objects", "Characters") 
      For ctr As Integer = 0 To chars.Count - 1 
         Console.WriteLine("{0,6} {1,20} {2,20}",
                           ctr, chars(ctr), elements(ctr)) 
      Next                        
   End Sub
End Module
' The example displays the following output:
'    Word #         Char Objects           Characters
'         0                    2                    2
'         1                    4                    4
'         2                    3                    3
'         3                    4                    4
'         4                    3                    3
'         5                    8                    8
'         6                    8                    7
'         7                    3                    3
'         8                    2                    2
'         9                    8                    8
'        10                    2                    1
'        11                    8                    8
'        12                    3                    3
'        13                    3                    3
'        14                    9                    9
'        15                   15                   15
'        16                    2                    2
'        17                    6                    6
'        18                   12                   12

此示例使用 StringInfo.GetTextElementEnumerator 方法和 TextElementEnumerator 类来枚举字符串中的所有文本元素,从而处理文本元素。 还可以通过调用 StringInfo.ParseCombiningCharacters 方法检索包含每个文本元素的起始索引的数组。

有关使用文本单位而不是单个 Char 值的详细信息,请参阅 .NET 中的字符编码简介

Null 字符串和空字符串

已声明但尚未分配值的字符串为 null。 尝试在该字符串上调用方法会引发一个 NullReferenceException。 null 字符串不同于空字符串,它是值为“”或 String.Empty的字符串。 在某些情况下,将 null 字符串或空字符串作为方法调用中的参数传递将引发异常。 例如,将 null 字符串传递给 Int32.Parse 方法将引发一个 ArgumentNullException,并传递空字符串将引发一个 FormatException。 在其他情况下,方法参数可以是 null 字符串或空字符串。 例如,如果要为类提供 IFormattable 实现,则希望将 null 字符串和空字符串等同于常规 (“G”) 格式说明符。

String 类包含以下两种方便方法,可用于测试字符串 null 是还是空:

  • IsNullOrEmpty,指示字符串 null 是还是等于 String.Empty。 此方法无需使用以下代码:

    if (str == nullptr || str->Equals(String::Empty))
    
    if (str == null || str.Equals(String.Empty))
    
    if str = null || str.Equals String.Empty then
    
    If str Is Nothing OrElse str.Equals(String.Empty) Then
    
  • IsNullOrWhiteSpace,它指示字符串 null是、等于 String.Empty还是只包含空格字符。 此方法无需使用以下代码:

    if (str == nullptr || str->Equals(String::Empty) || str->Trim()->Equals(String::Empty))
    
    if (str == null || str.Equals(String.Empty) || str.Trim().Equals(String.Empty))
    
    if str = null || str.Equals String.Empty || str.Trim().Equals String.Empty then
    
    If str Is Nothing OrElse str.Equals(String.Empty) OrElse str.Trim().Equals(String.Empty)
    

以下示例使用IsNullOrEmpty自定义Temperature类的实现中的IFormattable.ToString方法。 该方法支持“G”、“C”、“F”和“K”格式字符串。 如果空格式字符串或其值 null 传递给方法的格式字符串,则其值将更改为“G”格式字符串。

public:
   virtual String^ ToString(String^ format, IFormatProvider^ provider) 
   {
      if (String::IsNullOrEmpty(format)) format = "G";  
      if (provider == nullptr) provider = CultureInfo::CurrentCulture;
      
      switch (Convert::ToUInt16(format->ToUpperInvariant()))
      {
         // Return degrees in Celsius.    
         case 'G':
         case 'C':
            return temp.ToString("F2", provider) + L"�C";
         // Return degrees in Fahrenheit.
         case 'F': 
            return (temp * 9 / 5 + 32).ToString("F2", provider) + L"�F";
         // Return degrees in Kelvin.
         case 'K':   
            return (temp + 273.15).ToString();
         default:
            throw gcnew FormatException(
                  String::Format("The {0} format string is not supported.", 
                                 format));
      }                                   
   }
public string ToString(string format, IFormatProvider provider) 
{
   if (String.IsNullOrEmpty(format)) format = "G";  
   if (provider == null) provider = CultureInfo.CurrentCulture;
   
   switch (format.ToUpperInvariant())
   {
      // Return degrees in Celsius.    
      case "G":
      case "C":
         return temp.ToString("F2", provider) + "°C";
      // Return degrees in Fahrenheit.
      case "F": 
         return (temp * 9 / 5 + 32).ToString("F2", provider) + "°F";
      // Return degrees in Kelvin.
      case "K":   
         return (temp + 273.15).ToString();
      default:
         throw new FormatException(
               String.Format("The {0} format string is not supported.", 
                             format));
   }                                   
}
member _.ToString(format: string, provider: IFormatProvider) =
    let format = 
        if String.IsNullOrEmpty format then "G" else format
    
    let provider: IFormatProvider = 
        if provider = null then CultureInfo.CurrentCulture else provider

    match format.ToUpperInvariant() with
    // Return degrees in Celsius.
    | "G"
    | "C" ->
        temp.ToString("F2", provider) + "°C"
    // Return degrees in Fahrenheit.
    | "F" ->
        (temp * 9. / 5. + 32.).ToString("F2", provider) + "°F"
    // Return degrees in Kelvin.
    | "K" ->
        (temp + 273.15).ToString()
    | _ ->
        raise (FormatException(String.Format("The {0} format string is not supported.",format)))
Public Overloads Function ToString(fmt As String, provider As IFormatProvider) As String _
                Implements IFormattable.ToString
   If String.IsNullOrEmpty(fmt) Then fmt = "G"  
   If provider Is Nothing Then provider = CultureInfo.CurrentCulture
   
   Select Case fmt.ToUpperInvariant()
      ' Return degrees in Celsius.    
      Case "G", "C"
         Return temp.ToString("F2", provider) + "°C"
      ' Return degrees in Fahrenheit.
      Case "F" 
         Return (temp * 9 / 5 + 32).ToString("F2", provider) + "°F"
      ' Return degrees in Kelvin.
      Case "K"   
         Return (temp + 273.15).ToString()
      Case Else
         Throw New FormatException(
               String.Format("The {0} format string is not supported.", 
                             fmt))
    End Select                                   
End Function

不可变性和 StringBuilder 类

对象 String 称为不可变 (只读) ,因为创建对象后无法修改其值。 看似修改 String 对象的方法实际上返回包含修改的新 String 对象。

由于字符串是不可变的,因此对单个字符串执行重复添加或删除操作的字符串操作例程可以精确到明显的性能损失。 例如,以下代码使用随机数生成器创建一个字符串,该字符串的范围为 1000 个字符,0x0001 0x052F。 尽管代码似乎使用字符串串联将新字符追加到命名 str的现有字符串,但它实际上会为每个串联操作创建新 String 对象。

using namespace System;
using namespace System::IO;
using namespace System::Text;

void main()
{
   Random^ rnd = gcnew Random();

   String^ str = String::Empty;
   StreamWriter^ sw = gcnew StreamWriter(".\\StringFile.txt", 
                        false, Encoding::Unicode);

   for (int ctr = 0; ctr <= 1000; ctr++) {
      str += Convert::ToChar(rnd->Next(1, 0x0530)); 
      if (str->Length % 60 == 0)
         str += Environment::NewLine;          
   }                    
   sw->Write(str);
   sw->Close();
}
using System;
using System.IO;
using System.Text;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      
      string str = String.Empty;
      StreamWriter sw = new StreamWriter(@".\StringFile.txt", 
                           false, Encoding.Unicode);

      for (int ctr = 0; ctr <= 1000; ctr++) {
         str += (char)rnd.Next(1, 0x0530);
         if (str.Length % 60 == 0)
            str += Environment.NewLine;          
      }                    
      sw.Write(str);
      sw.Close();
   }
}
open System
open System.IO
open System.Text

do
    let rnd = Random()

    let mutable str = String.Empty
    use sw = new StreamWriter(@".\StringFile.txt", false, Encoding.Unicode)
    for _ = 0 to 1000 do
        str <- str + (rnd.Next(1, 0x0530) |> char |> string)
        if str.Length % 60 = 0 then
            str <- str + Environment.NewLine
    sw.Write str
Imports System.IO
Imports System.Text

Module Example
   Public Sub Main()
      Dim rnd As New Random()
      
      Dim str As String = String.Empty
      Dim sw As New StreamWriter(".\StringFile.txt", 
                           False, Encoding.Unicode)

      For ctr As Integer = 0 To 1000
         str += ChrW(rnd.Next(1, &h0530)) 
         If str.Length Mod 60 = 0 Then str += vbCrLf          
      Next                    
      sw.Write(str)
      sw.Close()
   End Sub
End Module

可以将 StringBuilder 类而不是 String 类用于对字符串值进行多次更改的操作。 与类的 String 实例不同, StringBuilder 对象是可变的;在字符串中连接、追加或删除子字符串时,操作将针对单个字符串执行。 修改完对象的值 StringBuilder 后,可以调用其 StringBuilder.ToString 方法将其转换为字符串。 以下示例替换 String 上一示例中用于将区域中的 1000 个随机字符连接在一起,以0x0001将0x052F与 StringBuilder 对象连接。

using namespace System;
using namespace System::IO;
using namespace System::Text;

void main()
{
   Random^ rnd = gcnew Random();

   StringBuilder^ sb = gcnew StringBuilder();
   StreamWriter^ sw = gcnew StreamWriter(".\\StringFile.txt", 
                        false, Encoding::Unicode);

   for (int ctr = 0; ctr <= 1000; ctr++) {
      sb->Append(Convert::ToChar(rnd->Next(1, 0x0530))); 
      if (sb->Length % 60 == 0)
         sb->AppendLine();          
   }                    
   sw->Write(sb->ToString());
   sw->Close();
}
using System;
using System.IO;
using System.Text;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      StringBuilder sb = new StringBuilder();
      StreamWriter sw = new StreamWriter(@".\StringFile.txt", 
                                         false, Encoding.Unicode);

      for (int ctr = 0; ctr <= 1000; ctr++) {
         sb.Append((char)rnd.Next(1, 0x0530));
         if (sb.Length % 60 == 0)
            sb.AppendLine();          
      }                    
      sw.Write(sb.ToString());
      sw.Close();
   }
}
open System
open System.IO
open System.Text

do
    let rnd = Random()
    let sb = StringBuilder()
    use sw = new StreamWriter(@".\StringFile.txt", false, Encoding.Unicode)

    for _ = 0 to 1000 do
        sb.Append(rnd.Next(1, 0x0530) |> char) |> ignore
        if sb.Length % 60 = 0 then
            sb.AppendLine() |> ignore
    sw.Write(string sb)
Imports System.IO
Imports System.Text

Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim sb As New StringBuilder()
      Dim sw As New StreamWriter(".\StringFile.txt", 
                                 False, Encoding.Unicode)

      For ctr As Integer = 0 To 1000
         sb.Append(ChrW(rnd.Next(1, &h0530))) 
         If sb.Length Mod 60 = 0 Then sb.AppendLine()          
      Next                    
      sw.Write(sb.ToString())
      sw.Close()
   End Sub
End Module

序号与区分区域性的操作

类的成员 String 对对象执行序号或区分区域性的 (语言) 操作 String 。 序号运算对每个 Char 对象的数值进行操作。 区分区域性的操作对对象的值 String 进行操作,并将特定于区域性的大小写、排序、格式设置和分析规则考虑在内。 区分区域性的操作在显式声明区域性或隐式当前区域性的上下文中执行。 这两种操作在对同一字符串执行时可能会产生非常不同的结果。

.NET 还通过使用固定区域性 () CultureInfo.InvariantCulture 支持不区分区域性的语言字符串操作,该区域性基于独立于区域的英语区域性设置松散。 System.Globalization.CultureInfo与其他设置不同,固定区域性的设置保证在单个计算机上、从系统到系统以及跨 .NET 版本保持一致。 固定区域性可以被视为一种黑盒,可确保字符串比较和在所有区域性中排序的稳定性。

重要

如果应用程序对符号标识符(如文件名或命名管道)或关于 XML 文件中基于文本的数据(如基于文本的数据)做出安全决策,则操作应使用序号比较而不是区分区域性的比较。 这是因为区分区域性的比较可能会产生不同的结果,具体取决于生效的区域性,而序号比较只依赖于比较字符的二进制值。

重要

执行字符串操作的大多数方法都包含具有类型 StringComparison参数的重载,这使你可以指定该方法执行序号或区分区域性的操作。 通常,应调用此重载,以便明确方法调用的意图。 有关对字符串使用序号和区分区域性的操作的最佳做法和指南,请参阅 有关使用字符串的最佳做法

大小写分析和格式设置比较和排序以及相等性测试的操作可以是序号或区域性敏感操作。 以下部分讨论每个操作类别。

提示

应始终调用方法重载,以便明确方法调用的意图。 例如,应使用当前区域性的约定调用方法,而不是调用Compare(String, String)方法对两个字符串执行区分区域性的比较,而应使用参数的值StringComparison.CurrentCulturecomparisonType调用Compare(String, String, StringComparison)该方法。 有关详细信息,请参阅有关使用字符串的最佳实践

可以从以下链接下载排序权重表、一组文本文件,其中包含有关排序和比较操作中使用的字符权重的信息:

大小写

大小写规则确定如何更改 Unicode 字符的大小写;例如,从小写到大写。 通常,在字符串比较之前执行大小写操作。 例如,可以将字符串转换为大写,以便将其与其他大写字符串进行比较。 可以通过调用 ToLowerToLowerInvariant 方法将字符串中的字符转换为小写,并通过调用 ToUpperToUpperInvariant 方法将其转换为大写。 此外,还可以使用 TextInfo.ToTitleCase 该方法将字符串转换为标题大小写。

备注

仅在 Linux 和 macOS 系统上运行的 .NET Core:C 和 Posix 区域性的排序规则行为始终区分大小写,因为这些区域性不使用预期的 Unicode 排序规则顺序。 建议使用除 C 或 Posix 以外的区域性执行区分区域性但不区分大小写的排序操作。

大小写操作可以基于当前区域性、指定区域性或固定区域性的规则。 由于大小写映射可能因所用区域性而异,因此大小写操作的结果可能因区域性而异。 大小写的实际差异有三种:

  • 拉丁文大写字母 I (U+0049) 、拉丁文小写字母 I (U+0069) 、带上点 (的拉丁文大写字母 I+0130) 以及拉丁文小写字母 DOTLESS I (U+0131) 。 在 tr-TR (土耳其 (土耳其) ) 和 az-Latn-AZ (阿塞拜疆、拉丁语) 文化中,在 tr、az 和 az-Latn 中性区域性中,拉丁文大写字母 I 是拉丁文小写字母 I 是拉丁文小写字母 I 和上面带点点的拉丁文小写字母 I。 在所有其他区域性中,包括固定区域性、拉丁文小写字母 I 和拉丁文大写字母 I 是小写和大写等效项。

    以下示例演示了如果字符串比较依赖于区分区域性的大小写比较,则用于防止文件系统访问失败。 (应使用固定区域性的大小写约定。)

    using System;
    using System.Globalization;
    using System.Threading;
    
    public class Example
    {
       const string disallowed = "file";
       
       public static void Main()
       {
          IsAccessAllowed(@"FILE:\\\c:\users\user001\documents\FinancialInfo.txt");
       }
    
       private static void IsAccessAllowed(String resource)
       {
          CultureInfo[] cultures = { CultureInfo.CreateSpecificCulture("en-US"),
                                     CultureInfo.CreateSpecificCulture("tr-TR") };
          String scheme = null;
          int index = resource.IndexOfAny( new Char[] { '\\', '/' } );
          if (index > 0) 
             scheme = resource.Substring(0, index - 1);
    
          // Change the current culture and perform the comparison.
          foreach (var culture in cultures) {
             Thread.CurrentThread.CurrentCulture = culture;
             Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName);
             Console.WriteLine(resource);
             Console.WriteLine("Access allowed: {0}", 
                               ! String.Equals(disallowed, scheme, StringComparison.CurrentCultureIgnoreCase));      
             Console.WriteLine();
          }   
       }
    }
    // The example displays the following output:
    //       Culture: English (United States)
    //       FILE:\\\c:\users\user001\documents\FinancialInfo.txt
    //       Access allowed: False
    //       
    //       Culture: Turkish (Turkey)
    //       FILE:\\\c:\users\user001\documents\FinancialInfo.txt
    //       Access allowed: True
    
    open System
    open System.Globalization
    open System.Threading
    
    let disallowed = "file"
    
    let isAccessAllowed (resource: string) =
        let cultures = 
            [| CultureInfo.CreateSpecificCulture "en-US"
               CultureInfo.CreateSpecificCulture "tr-TR" |]
        let index = resource.IndexOfAny [| '\\'; '/' |]
        let scheme =
            if index > 0 then
                resource.Substring(0, index - 1)
            else 
                null
    
        // Change the current culture and perform the comparison.
        for culture in cultures do
            Thread.CurrentThread.CurrentCulture <- culture
            printfn $"Culture: {CultureInfo.CurrentCulture.DisplayName}"
            printfn $"{resource}"
            printfn $"Access allowed: {String.Equals(disallowed, scheme, StringComparison.CurrentCultureIgnoreCase) |> not}"
            printfn ""
            
    isAccessAllowed @"FILE:\\\c:\users\user001\documents\FinancialInfo.txt"
    // The example displays the following output:
    //       Culture: English (United States)
    //       FILE:\\\c:\users\user001\documents\FinancialInfo.txt
    //       Access allowed: False
    //
    //       Culture: Turkish (Turkey)
    //       FILE:\\\c:\users\user001\documents\FinancialInfo.txt
    //       Access allowed: True
    
    Imports System.Globalization
    Imports System.Threading
    
    Module Example
       Const disallowed = "file"
       
       Public Sub Main()
          IsAccessAllowed("FILE:\\\c:\users\user001\documents\FinancialInfo.txt")
       End Sub
    
       Private Sub IsAccessAllowed(resource As String)
          Dim cultures() As CultureInfo = { CultureInfo.CreateSpecificCulture("en-US"),
                                            CultureInfo.CreateSpecificCulture("tr-TR") }
          Dim scheme As String = Nothing
          Dim index As Integer = resource.IndexOfAny( {"\"c, "/"c })
          If index > 0 Then scheme = resource.Substring(0, index - 1)
    
          ' Change the current culture and perform the comparison.
          For Each culture In cultures
             Thread.CurrentThread.CurrentCulture = culture
             Console.WriteLine("Culture: {0}", CultureInfo.CurrentCulture.DisplayName)
             Console.WriteLine(resource)
             Console.WriteLine("Access allowed: {0}", 
                               Not String.Equals(disallowed, scheme, StringComparison.CurrentCultureIgnoreCase))      
             Console.WriteLine()
          Next   
       End Sub      
    End Module
    ' The example displays the following output:
    '       Culture: English (United States)
    '       FILE:\\\c:\users\user001\documents\FinancialInfo.txt
    '       Access allowed: False
    '       
    '       Culture: Turkish (Turkey)
    '       FILE:\\\c:\users\user001\documents\FinancialInfo.txt
    '       Access allowed: True
    
  • 固定区域性与所有其他区域性之间的映射差异。 在这些情况下,使用固定区域性的大小写规则将字符更改为大写或小写将返回相同的字符。 对于所有其他区域性,它将返回不同的字符。 下表列出了一些受影响的字符。

    字符 如果更改为 返回
    MICRO SIGN (U+00B5) 大写 希腊文大写字母 MU (U+-39C)
    带上点的拉丁文大写字母 I (U+0130) 小写 拉丁文小写字母 I (U+0069)
    拉丁文小写字母 DOTLESS I (U+0131) 大写 拉丁文大写字母 I (U+0049)
    拉丁文小写字母 LONG S (U+017F) 大写 拉丁文大写字母 S (U+0053)
    带小写字母 Z 和 CARON 的拉丁文大写字母 D (U+01C5) 小写 带 CARON (U+01C6) 的拉丁文小写字母 DZ
    组合希腊文 YPOGEGRAMMENI (U+0345) 大写 希腊文大写字母 IOTA (U+0399)
  • ASCII 字符范围中双字母混合大小写对事例映射的差异。 在大多数区域性中,双字母混合大小写配对等于等效的双字母大写或小写配对。 对于以下区域性中的以下两个字母对来说,这并不真实,因为在每个情况下,它们都与日记进行比较:

    • hr-HR (克罗地亚 (克罗地亚) ) 区域性中的“lJ”和“nJ”。

    • cs-CZ 中的“cH” (捷克 (捷克共和国) ) 和 sk-SK (斯洛伐克 (斯洛伐克) ) 区域性。

    • da-DK 中的“aA” (丹麦 (丹麦) ) 区域性。

    • “cS”、“dZ”、“dZS”、“nY”、“sZ”、“tY”和“zS”位于 hu-HU (匈牙利 (匈牙利) ) 文化中。

    • es-ES_tradnl (西班牙 (传统排序) ) 区域性中的“cH”和“lL”。

    • vi-VN (越南语 (越南) ) 区域性中的“cH”、“gI”、“kH”、“nH”、“nH”、“pH”、“qU'、tH”和“tR”。

    但是,遇到这种情况下,这些对的区域性敏感比较会产生问题,因为这些对在固定字符串或标识符中并不常见。

以下示例演示了将字符串转换为大写时区域性大小写规则之间的一些差异。

using namespace System;
using namespace System::Globalization;
using namespace System::IO;

String^ ShowHexValue(String^ s);

void main()
{
   StreamWriter^ sw = gcnew StreamWriter(".\\case.txt");   
   array<String^>^ words = gcnew array<String^> { L"file", L"sıfır", L"Dženana" };
   array<CultureInfo^>^ cultures = gcnew array<CultureInfo^> { CultureInfo::InvariantCulture, 
                                                               gcnew CultureInfo("en-US"),  
                                                               gcnew CultureInfo("tr-TR") };

   for each (String^ word in words) {
      sw->WriteLine("{0}:", word);
      for each (CultureInfo^ culture in cultures) {
         String^ name = String::IsNullOrEmpty(culture->Name) ? 
                              "Invariant" : culture->Name;
         String^ upperWord = word->ToUpper(culture);
         sw->WriteLine("   {0,10}: {1,7} {2, 38}", name, 
                        upperWord, ShowHexValue(upperWord));

      }
      sw->WriteLine();  
   }
   sw->Close();
}

String^ ShowHexValue(String^ s)
{
   String^ retval = nullptr;
   for each (Char ch in s) {
      array<Byte>^ bytes = BitConverter::GetBytes(ch);
      retval += String::Format("{0:X2} {1:X2} ", bytes[1], bytes[0]);     
   }
   return retval;
} 
// The example displays the following output: 
//    file: 
//        Invariant:    FILE               00 46 00 49 00 4C 00 45  
//            en-US:    FILE               00 46 00 49 00 4C 00 45  
//            tr-TR:    FİLE               00 46 01 30 00 4C 00 45  
//     
//    sıfır: 
//        Invariant:   SıFıR         00 53 01 31 00 46 01 31 00 52  
//            en-US:   SIFIR         00 53 00 49 00 46 00 49 00 52  
//            tr-TR:   SIFIR         00 53 00 49 00 46 00 49 00 52  
//     
//    Dženana: 
//        Invariant:  DžENANA   01 C5 00 45 00 4E 00 41 00 4E 00 41  
//            en-US:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41  
//            tr-TR:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41
using System;
using System.Globalization;
using System.IO;

public class Example
{
   public static void Main()
   {
      StreamWriter sw = new StreamWriter(@".\case.txt");   
      string[] words = { "file", "sıfır", "Dženana" };
      CultureInfo[] cultures = { CultureInfo.InvariantCulture, 
                                 new CultureInfo("en-US"),  
                                 new CultureInfo("tr-TR") };

      foreach (var word in words) {
         sw.WriteLine("{0}:", word);
         foreach (var culture in cultures) {
            string name = String.IsNullOrEmpty(culture.Name) ? 
                                 "Invariant" : culture.Name;
            string upperWord = word.ToUpper(culture);
            sw.WriteLine("   {0,10}: {1,7} {2, 38}", name, 
                         upperWord, ShowHexValue(upperWord));
         }
         sw.WriteLine();  
      }
      sw.Close();
   }

   private static string ShowHexValue(string s)
   {
      string retval = null;
      foreach (var ch in s) {
         byte[] bytes = BitConverter.GetBytes(ch);
         retval += String.Format("{0:X2} {1:X2} ", bytes[1], bytes[0]);     
      }
      return retval;
   } 
}
// The example displays the following output:
//    file:
//        Invariant:    FILE               00 46 00 49 00 4C 00 45 
//            en-US:    FILE               00 46 00 49 00 4C 00 45 
//            tr-TR:    FİLE               00 46 01 30 00 4C 00 45 
//    
//    sıfır:
//        Invariant:   SıFıR         00 53 01 31 00 46 01 31 00 52 
//            en-US:   SIFIR         00 53 00 49 00 46 00 49 00 52 
//            tr-TR:   SIFIR         00 53 00 49 00 46 00 49 00 52 
//    
//    Dženana:
//        Invariant:  DžENANA   01 C5 00 45 00 4E 00 41 00 4E 00 41 
//            en-US:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41 
//            tr-TR:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41
open System
open System.Globalization
open System.IO

let showHexValue (s: string) =
    let mutable retval = ""
    for ch in s do
        let bytes = BitConverter.GetBytes ch
        retval <- retval + String.Format("{0:X2} {1:X2} ", bytes[1], bytes[0])
    retval

do
    use sw = new StreamWriter(@".\case.txt")
    let words = [| "file"; "sıfır"; "Dženana" |]
    let cultures = 
        [| CultureInfo.InvariantCulture 
           CultureInfo "en-US"
           CultureInfo "tr-TR" |]

    for word in words do
        sw.WriteLine("{0}:", word)
        for culture in cultures do
            let name =
                 if String.IsNullOrEmpty culture.Name then "Invariant" else culture.Name
            let upperWord = word.ToUpper culture
            sw.WriteLine("   {0,10}: {1,7} {2, 38}", name, upperWord, showHexValue upperWord)
        sw.WriteLine()
    sw.Close()

// The example displays the following output:
//    file:
//        Invariant:    FILE               00 46 00 49 00 4C 00 45
//            en-US:    FILE               00 46 00 49 00 4C 00 45
//            tr-TR:    FİLE               00 46 01 30 00 4C 00 45
//
//    sıfır:
//        Invariant:   SıFıR         00 53 01 31 00 46 01 31 00 52
//            en-US:   SIFIR         00 53 00 49 00 46 00 49 00 52
//            tr-TR:   SIFIR         00 53 00 49 00 46 00 49 00 52
//
//    Dženana:
//        Invariant:  DžENANA   01 C5 00 45 00 4E 00 41 00 4E 00 41
//            en-US:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41
//            tr-TR:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41
Imports System.Globalization
Imports System.IO

Module Example
   Public Sub Main()
      Dim sw As New StreamWriter(".\case.txt")   
      Dim words As String() = { "file", "sıfır", "Dženana" }
      Dim cultures() As CultureInfo = { CultureInfo.InvariantCulture, 
                                        New CultureInfo("en-US"),  
                                        New CultureInfo("tr-TR") }

      For Each word In words
         sw.WriteLine("{0}:", word)
         For Each culture In cultures
            Dim name As String = If(String.IsNullOrEmpty(culture.Name),  
                                 "Invariant", culture.Name)
            Dim upperWord As String = word.ToUpper(culture)
            sw.WriteLine("   {0,10}: {1,7} {2, 38}", name, 
                         upperWord, ShowHexValue(upperWord))
     
         Next
         sw.WriteLine()  
      Next
      sw.Close()
   End Sub

   Private Function ShowHexValue(s As String) As String
      Dim retval As String = Nothing
      For Each ch In s
         Dim bytes() As Byte = BitConverter.GetBytes(ch)
         retval += String.Format("{0:X2} {1:X2} ", bytes(1), bytes(0))     
      Next
      Return retval
   End Function
End Module
' The example displays the following output:
'    file:
'        Invariant:    FILE               00 46 00 49 00 4C 00 45 
'            en-US:    FILE               00 46 00 49 00 4C 00 45 
'            tr-TR:    FİLE               00 46 01 30 00 4C 00 45 
'    
'    sıfır:
'        Invariant:   SıFıR         00 53 01 31 00 46 01 31 00 52 
'            en-US:   SIFIR         00 53 00 49 00 46 00 49 00 52 
'            tr-TR:   SIFIR         00 53 00 49 00 46 00 49 00 52 
'    
'    Dženana:
'        Invariant:  DžENANA   01 C5 00 45 00 4E 00 41 00 4E 00 41 
'            en-US:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41 
'            tr-TR:  DŽENANA   01 C4 00 45 00 4E 00 41 00 4E 00 41

分析和格式设置

格式设置和分析是逆操作。 格式规则确定如何将值(如日期和时间或数字)转换为其字符串表示形式,而分析规则确定如何将字符串表示形式转换为日期和时间等值。 格式设置和分析规则都依赖于文化约定。 下面的示例说明了解释区域性特定的日期字符串时可能出现的歧义性。 不知道用于生成日期字符串的区域性约定,则无法知道 2011 年 3 月 1 日、2011 年 3 月 1 日和 2011 年 1 月 3 日和 2011 年 1 月 3 日或 2011 年 3 月 1 日是否为 03/03。

using namespace System;
using namespace System::Globalization;

void main()
{
   DateTime^ date = gcnew DateTime(2011, 3, 1);
   array<CultureInfo^>^ cultures = gcnew array<CultureInfo^> { CultureInfo::InvariantCulture, 
                                                               gcnew CultureInfo("en-US"), 
                                                               gcnew CultureInfo("fr-FR") };

   for each (CultureInfo^ culture in cultures)
      Console::WriteLine("{0,-12} {1}", String::IsNullOrEmpty(culture->Name) ?
                        "Invariant" : culture->Name, 
                        date->ToString("d", culture));                                    
}
// The example displays the following output: 
//       Invariant    03/01/2011 
//       en-US        3/1/2011 
//       fr-FR        01/03/2011
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date = new DateTime(2011, 3, 1);
      CultureInfo[] cultures = { CultureInfo.InvariantCulture, 
                                 new CultureInfo("en-US"), 
                                 new CultureInfo("fr-FR") };

      foreach (var culture in cultures)
         Console.WriteLine("{0,-12} {1}", String.IsNullOrEmpty(culture.Name) ?
                           "Invariant" : culture.Name, 
                           date.ToString("d", culture));                                    
   }
}
// The example displays the following output:
//       Invariant    03/01/2011
//       en-US        3/1/2011
//       fr-FR        01/03/2011
open System
open System.Globalization

let date = DateTime(2011, 3, 1)
let cultures = 
      [| CultureInfo.InvariantCulture
         CultureInfo "en-US"
         CultureInfo "fr-FR" |]

for culture in cultures do
    printfn $"""{(if String.IsNullOrEmpty culture.Name then "Invariant" else culture.Name),-12} {date.ToString("d", culture)}"""
// The example displays the following output:
//       Invariant    03/01/2011
//       en-US        3/1/2011
//       fr-FR        01/03/2011
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim dat As Date = #3/1/2011#
      Dim cultures() As CultureInfo = { CultureInfo.InvariantCulture, 
                                        New CultureInfo("en-US"), 
                                        New CultureInfo("fr-FR") }

      For Each culture In cultures
         Console.WriteLine("{0,-12} {1}", If(String.IsNullOrEmpty(culture.Name), 
                           "Invariant", culture.Name), 
                           dat.ToString("d", culture))
      Next                                                         
   End Sub
End Module
' The example displays the following output:
'       Invariant    03/01/2011
'       en-US        3/1/2011
'       fr-FR        01/03/2011

同样,如以下示例所示,单个字符串可以生成不同的日期,具体取决于其约定在分析操作中使用的区域性。

using namespace System;
using namespace System::Globalization;

void main()
{
   String^ dateString = "07/10/2011";
   array<CultureInfo^>^ cultures = gcnew array<CultureInfo^> { CultureInfo::InvariantCulture, 
                                                               CultureInfo::CreateSpecificCulture("en-GB"), 
                                                               CultureInfo::CreateSpecificCulture("en-US") };
   Console::WriteLine("{0,-12} {1,10} {2,8} {3,8}\n", "Date String", "Culture", 
                                                "Month", "Day");
   for each (CultureInfo^ culture in cultures) {
      DateTime date = DateTime::Parse(dateString, culture);
      Console::WriteLine("{0,-12} {1,10} {2,8} {3,8}", dateString, 
                        String::IsNullOrEmpty(culture->Name) ?
                        "Invariant" : culture->Name, 
                        date.Month, date.Day);
   }                      
}
// The example displays the following output: 
//       Date String     Culture    Month      Day 
//        
//       07/10/2011    Invariant        7       10 
//       07/10/2011        en-GB       10        7 
//       07/10/2011        en-US        7       10
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string dateString = "07/10/2011";
      CultureInfo[] cultures = { CultureInfo.InvariantCulture, 
                                 CultureInfo.CreateSpecificCulture("en-GB"), 
                                 CultureInfo.CreateSpecificCulture("en-US") };
      Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}\n", "Date String", "Culture", 
                                                 "Month", "Day");
      foreach (var culture in cultures) {
         DateTime date = DateTime.Parse(dateString, culture);
         Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", dateString, 
                           String.IsNullOrEmpty(culture.Name) ?
                           "Invariant" : culture.Name, 
                           date.Month, date.Day);
      }                      
   }
}
// The example displays the following output:
//       Date String     Culture    Month      Day
//       
//       07/10/2011    Invariant        7       10
//       07/10/2011        en-GB       10        7
//       07/10/2011        en-US        7       10
open System
open System.Globalization

let dateString = "07/10/2011"
let cultures = 
    [| CultureInfo.InvariantCulture
       CultureInfo.CreateSpecificCulture "en-GB"
       CultureInfo.CreateSpecificCulture "en-US" |]
printfn $"""{"Date String",-12} {"Culture",10} {"Month",8} {"Day",8}\n"""
for culture in cultures do
    let date = DateTime.Parse(dateString, culture)
    printfn $"""{dateString,-12} {(if String.IsNullOrEmpty culture.Name then "Invariant" else culture.Name),10} {date.Month,8} {date.Day,8}"""
// The example displays the following output:
//       Date String     Culture    Month      Day
//
//       07/10/2011    Invariant        7       10
//       07/10/2011        en-GB       10        7
//       07/10/2011        en-US        7       10
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim dateString As String = "07/10/2011"
      Dim cultures() As CultureInfo = { CultureInfo.InvariantCulture, 
                                        CultureInfo.CreateSpecificCulture("en-GB"), 
                                        CultureInfo.CreateSpecificCulture("en-US") }
      Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", "Date String", "Culture", 
                                                 "Month", "Day")
      Console.WriteLine()                                                 
      For Each culture In cultures
         Dim dat As Date = DateTime.Parse(dateString, culture)
         Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", dateString, 
                           If(String.IsNullOrEmpty(culture.Name), 
                           "Invariant", culture.Name), 
                           dat.Month, dat.Day)
      Next
   End Sub
End Module
' The example displays the following output:
'       Date String     Culture    Month      Day
'       
'       07/10/2011    Invariant        7       10
'       07/10/2011        en-GB       10        7
'       07/10/2011        en-US        7       10

字符串比较和排序

用于比较和排序字符串的约定因区域性而异。 例如,排序顺序可能基于拼音或字符的视觉表示形式。 在东亚语言中,按文字的笔画和部首对字符进行排序。 排序也取决于字母表使用的排序语言和区域性。 例如,丹麦语有一个“Æ”字符,它在字母表中按“Z”排序。 此外,比较可能区分大小写或区分大小写,大小写规则可能因区域性而异。 另一方面,序号比较在比较和排序字符串时使用字符串中各个字符的 Unicode 码点。

排序规则确定 Unicode 字符的字母顺序以及两个字符串相互比较的方式。 例如,该方法 String.Compare(String, String, StringComparison) 基于 StringComparison 参数比较两个字符串。 如果参数值为 StringComparison.CurrentCulture,则该方法执行使用当前区域性约定的语言比较;如果参数值为 StringComparison.Ordinal,则该方法执行序号比较。 因此,如以下示例所示,如果当前区域性为美国英语,则使用区分区域性的比较) 对方法的第一次调用 String.Compare(String, String, StringComparison) (认为“a”小于“A”,但第二次调用相同的方法 (使用序号比较) 认为“a”大于“A”。

using namespace System;
using namespace System::Globalization;
using namespace System::Threading;

void main()
{
   Thread::CurrentThread->CurrentCulture = CultureInfo::CreateSpecificCulture("en-US");
   Console::WriteLine(String::Compare("A", "a", StringComparison::CurrentCulture));
   Console::WriteLine(String::Compare("A", "a", StringComparison::Ordinal));
}
// The example displays the following output: 
//       1 
//       -32
using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
      Console.WriteLine(String.Compare("A", "a", StringComparison.CurrentCulture));
      Console.WriteLine(String.Compare("A", "a", StringComparison.Ordinal));
   }
}
// The example displays the following output:
//       1
//       -32
open System
open System.Globalization
open System.Threading

Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-US"
printfn $"""{String.Compare("A", "a", StringComparison.CurrentCulture)}"""
printfn $"""{String.Compare("A", "a", StringComparison.Ordinal)}"""
// The example displays the following output:
//       1
//       -32
Imports System.Globalization
Imports System.Threading

Module Example
   Public Sub Main()
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")
      Console.WriteLine(String.Compare("A", "a", StringComparison.CurrentCulture))
      Console.WriteLine(String.Compare("A", "a", StringComparison.Ordinal))
   End Sub
End Module
' The example displays the following output:
'       1                                                                                     
'       -32

.NET 支持单词、字符串和序号排序规则:

  • 单词排序对字符串执行区分区域性的比较,在该比较中,某些非虚拟 Unicode 字符可能为其分配了特殊权重。 例如,连字符 () 可能分配了很小的权重,以便“coop”和“co-op”在排序列表中彼此旁边显示。 有关使用单词排序规则比较两个字符串的方法的列表 String ,请参阅 “按类别划分的字符串操作 ”部分。

  • 字符串排序还会执行区分区域性的比较。 它类似于单词排序,只不过没有特殊情况,所有非字母数字符号都位于所有字母数字 Unicode 字符之前。 通过调用CompareInfo.Compare具有提供值CompareOptions.StringSort的参数的方法重载,可以使用字符串排序规则比较两个options字符串。 请注意,这是 .NET 提供的唯一方法,用于使用字符串排序规则比较两个字符串。

  • 序号排序基于字符串中每个 Char 对象的数值比较字符串。 序号比较自动区分大小写,因为字符的小写和大写版本具有不同的代码点。 但是,如果事例不重要,可以指定忽略事例的序号比较。 这相当于使用固定区域性将字符串转换为大写,然后对结果执行序号比较。 有关使用序号排序规则比较两个字符串的方法的列表 String ,请参阅 “按类别划分的字符串操作 ”部分。

区分区域性的比较是显式或隐式使用 CultureInfo 对象的任何比较,包括属性指定的 CultureInfo.InvariantCulture 固定区域性。 隐式区域性是当前区域性,由 Thread.CurrentCulture 属性 CultureInfo.CurrentCulture 指定。 (字母字符的排序顺序存在相当大的变化,即属性true返回) 跨区域性的字符Char.IsLetter。 可以通过向字符串比较方法(例如Compare(String, String, CultureInfo, CompareOptions))提供CultureInfo对象来指定使用特定区域性约定的区分区域性的比较。 可以通过提供StringComparison.CurrentCulture、或枚举的任何成员来指定区分区域性的比较,该比较使用当前区域性的约定,或者指定方法的相应重载Compare以外的任何成员CompareOptions CompareOptions.Ordinal CompareOptions.OrdinalIgnoreCaseStringComparison.CurrentCultureIgnoreCase 区分区域性的比较通常适用于排序,而序号比较则不适合排序。 序号比较通常用于确定两个字符串是否相等 (,即确定标识) 而区分区域性的比较。

下面的示例演示了区分区域性和序号比较之间的差异。 该示例使用序号比较和 da-DK 和 en-US 区域性的约定计算三个字符串“Apple”、“Æble”和“AEble”, (其中每个字符串都是在方法调用) 时 Compare 的默认区域性。 由于丹麦语将字符“Æ”视为单个字母,并在字母表的“Z”之后对其进行排序,因此字符串“Æble”大于“Apple”。 但是,“Æble”不被视为等效于“AEble”,因此“Æble”也大于“AEble”。 en-US 区域性不包括字母“Æ”,但将其视为等效于“AE”,这解释了为什么“Æble”小于“Apple”,但等于“AEble”。 另一方面,序号比较认为“Apple”小于“Æble”,而“Æble”则大于“AEble”。

using System;
using System.Globalization;
using System.Threading;

public class CompareStringSample
{
   public static void Main()
   {
      string str1 = "Apple";
      string str2 = "Æble"; 
      string str3 = "AEble";
      
      // Set the current culture to Danish in Denmark.
      Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
      Console.WriteLine("Current culture: {0}", 
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str1, str2, String.Compare(str1, str2));
      Console.WriteLine("Comparison of {0} with {1}: {2}\n", 
                        str2, str3, String.Compare(str2, str3));
      
      // Set the current culture to English in the U.S.
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      Console.WriteLine("Current culture: {0}", 
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str1, str2, String.Compare(str1, str2));
      Console.WriteLine("Comparison of {0} with {1}: {2}\n", 
                        str2, str3, String.Compare(str2, str3));
      
      // Perform an ordinal comparison.
      Console.WriteLine("Ordinal comparison");
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str1, str2, 
                        String.Compare(str1, str2, StringComparison.Ordinal));
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str2, str3, 
                        String.Compare(str2, str3, StringComparison.Ordinal));
   }
}
// The example displays the following output:
//       Current culture: da-DK
//       Comparison of Apple with Æble: -1
//       Comparison of Æble with AEble: 1
//       
//       Current culture: en-US
//       Comparison of Apple with Æble: 1
//       Comparison of Æble with AEble: 0
//       
//       Ordinal comparison
//       Comparison of Apple with Æble: -133
//       Comparison of Æble with AEble: 133
open System
open System.Globalization
open System.Threading

let str1 = "Apple"
let str2 = "Æble"
let str3 = "AEble"

// Set the current culture to Danish in Denmark.
Thread.CurrentThread.CurrentCulture <- CultureInfo "da-DK"
printfn $"Current culture: {CultureInfo.CurrentCulture.Name}"
printfn $"Comparison of {str1} with {str2}: {String.Compare(str1, str2)}"
printfn $"Comparison of {str2} with {str3}: {String.Compare(str2, str3)}\n"

// Set the current culture to English in the U.S.
Thread.CurrentThread.CurrentCulture <- CultureInfo "en-US"
printfn $"Current culture: {CultureInfo.CurrentCulture.Name}"
printfn $"Comparison of {str1} with {str2}: {String.Compare(str1, str2)}"
printfn $"Comparison of {str2} with {str3}: {String.Compare(str2, str3)}\n"

// Perform an ordinal comparison.
printfn "Ordinal comparison"
printfn $"Comparison of {str1} with {str2}: {String.Compare(str1, str2, StringComparison.Ordinal)}"
printfn $"Comparison of {str2} with {str3}: {String.Compare(str2, str3, StringComparison.Ordinal)}"
// The example displays the following output:
//       Current culture: da-DK
//       Comparison of Apple with Æble: -1
//       Comparison of Æble with AEble: 1
//
//       Current culture: en-US
//       Comparison of Apple with Æble: 1
//       Comparison of Æble with AEble: 0
//
//       Ordinal comparison
//       Comparison of Apple with Æble: -133
//       Comparison of Æble with AEble: 133
Imports System.Globalization
Imports System.Threading

Public Module Example
   Public Sub Main()
      Dim str1 As String = "Apple"
      Dim str2 As String = "Æble"
      Dim str3 As String = "AEble"
      
      ' Set the current culture to Danish in Denmark.
      Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
      Console.WriteLine("Current culture: {0}", 
                        CultureInfo.CurrentCulture.Name)
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str1, str2, String.Compare(str1, str2))
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str2, str3, String.Compare(str2, str3))
      Console.WriteLine()
      
      ' Set the current culture to English in the U.S.
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      Console.WriteLine("Current culture: {0}", 
                        CultureInfo.CurrentCulture.Name)
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str1, str2, String.Compare(str1, str2))
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str2, str3, String.Compare(str2, str3))
      Console.WriteLine()
      
      ' Perform an ordinal comparison.
      Console.WriteLine("Ordinal comparison")
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str1, str2, 
                        String.Compare(str1, str2, StringComparison.Ordinal))
      Console.WriteLine("Comparison of {0} with {1}: {2}", 
                        str2, str3, 
                        String.Compare(str2, str3, StringComparison.Ordinal))
   End Sub
End Module
' The example displays the following output:
'       Current culture: da-DK
'       Comparison of Apple with Æble: -1
'       Comparison of Æble with AEble: 1
'       
'       Current culture: en-US
'       Comparison of Apple with Æble: 1
'       Comparison of Æble with AEble: 0
'       
'       Ordinal comparison
'       Comparison of Apple with Æble: -133
'       Comparison of Æble with AEble: 133

使用以下常规准则选择适当的排序或字符串比较方法:

  • 如果希望根据用户的区域性对字符串进行排序,则应根据当前区域性的约定对字符串进行排序。 如果用户的区域性发生更改,排序字符串的顺序也会相应地更改。 例如,同义词库应用程序应始终根据用户的区域性对单词进行排序。

  • 如果希望根据特定区域性的约定对字符串进行排序,则应通过向比较方法提供 CultureInfo 表示该区域性的对象来对其进行排序。 例如,在旨在教授学生特定语言的应用程序中,你希望根据讲该语言的某个区域性的约定对字符串进行排序。

  • 如果希望字符串的顺序在不同区域性中保持不变,则应根据固定区域性的约定对字符串进行排序,或使用序号比较。 例如,可以使用序号排序来组织文件、进程、互斥体或命名管道的名称。

  • 对于涉及安全决策 ((例如用户名是否有效) )的比较,应始终通过调用方法重 Equals 载对等性执行序号测试。

备注

字符串比较中使用的区分区域性的排序和大小写规则取决于 .NET 的版本。 在 .NET Core 上,字符串比较取决于基础操作系统支持的 Unicode Standard 版本。 在 .NET Framework Windows 8 或更高版本上运行的 4.5 及更高版本中,排序、大小写、规范化和 Unicode 字符信息符合 Unicode 6.0 标准。 在其他Windows操作系统上,它们符合 Unicode 5.0 标准。

有关单词、字符串和序号排序规则的详细信息,请参阅 System.Globalization.CompareOptions 主题。 有关何时使用每个规则的其他建议,请参阅 有关使用字符串的最佳做法

通常,不调用字符串比较方法,例如 Compare 直接确定字符串的排序顺序。 相反,比较方法是通过排序方法(如 Array.SortList<T>.Sort) 调用的。 以下示例使用当前区域性执行四种不同的排序操作 (单词排序,) 使用固定区域性、序号排序和字符串排序,而不显式调用字符串比较方法,尽管它们确实指定要使用的比较类型。 请注意,每种类型的排序在其数组中生成字符串的唯一排序。

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;
using namespace System::Globalization;

// IComparer<String> implementation to perform string sort. 
ref class SCompare : System::Collections::Generic::IComparer<String^>
{
public:
   SCompare() {};

   virtual int Compare(String^ x, String^ y)
   {
      return CultureInfo::CurrentCulture->CompareInfo->Compare(x, y, CompareOptions::StringSort);
   }
};

void main()
{
   array<String^>^ strings = gcnew array<String^> { "coop", "co-op", "cooperative", 
                                                    L"co\x00ADoperative", L"c�ur", "coeur" };

   // Perform a word sort using the current (en-US) culture. 
   array<String^>^ current = gcnew array<String^>(strings->Length); 
   strings->CopyTo(current, 0); 
   Array::Sort(current, StringComparer::CurrentCulture);

   // Perform a word sort using the invariant culture. 
   array<String^>^ invariant = gcnew array<String^>(strings->Length);
   strings->CopyTo(invariant, 0); 
   Array::Sort(invariant, StringComparer::InvariantCulture);

   // Perform an ordinal sort. 
   array<String^>^ ordinal = gcnew array<String^>(strings->Length);
   strings->CopyTo(ordinal, 0); 
   Array::Sort(ordinal, StringComparer::Ordinal);

   // Perform a string sort using the current culture. 
   array<String^>^ stringSort = gcnew array<String^>(strings->Length);
   strings->CopyTo(stringSort, 0); 
   Array::Sort(stringSort, gcnew SCompare());

   // Display array values
   Console::WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}\n", 
                     "Original", "Word Sort", "Invariant Word", 
                     "Ordinal Sort", "String Sort");
   for (int ctr = 0; ctr < strings->Length; ctr++)
      Console::WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}", 
                         strings[ctr], current[ctr], invariant[ctr], 
                         ordinal[ctr], stringSort[ctr] );          
}
// The example displays the following output: 
//         Original     Word Sort  Invariant Word  Ordinal Sort   String Sort 
//     
//             coop          c�ur            c�ur         co-op         co-op 
//            co-op         coeur           coeur         coeur          c�ur 
//      cooperative          coop            coop          coop         coeur 
//      co�operative         co-op           co-op   cooperative          coop 
//             c�ur   cooperative     cooperative   co�operative   cooperative 
//            coeur   co�operative     co�operative          c�ur   co�operative
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
 
public class Example
{
   public static void Main()
   {
      string[] strings = { "coop", "co-op", "cooperative", 
                           "co\u00ADoperative", "cœur", "coeur" };

      // Perform a word sort using the current (en-US) culture.
      string[] current = new string[strings.Length]; 
      strings.CopyTo(current, 0); 
      Array.Sort(current, StringComparer.CurrentCulture);

      // Perform a word sort using the invariant culture.
      string[] invariant = new string[strings.Length];
      strings.CopyTo(invariant, 0); 
      Array.Sort(invariant, StringComparer.InvariantCulture);

      // Perform an ordinal sort.
      string[] ordinal = new string[strings.Length];
      strings.CopyTo(ordinal, 0); 
      Array.Sort(ordinal, StringComparer.Ordinal);

      // Perform a string sort using the current culture.
      string[] stringSort = new string[strings.Length];
      strings.CopyTo(stringSort, 0); 
      Array.Sort(stringSort, new SCompare());

      // Display array values
      Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}\n", 
                        "Original", "Word Sort", "Invariant Word", 
                        "Ordinal Sort", "String Sort");
      for (int ctr = 0; ctr < strings.Length; ctr++)
         Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}", 
                           strings[ctr], current[ctr], invariant[ctr], 
                           ordinal[ctr], stringSort[ctr] );          
   }
}

// IComparer<String> implementation to perform string sort.
internal class SCompare : IComparer<String>
{
   public int Compare(string x, string y)
   {
      return CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort);
   }
}
// The example displays the following output:
//         Original     Word Sort  Invariant Word  Ordinal Sort   String Sort
//    
//             coop          cœur            cœur         co-op         co-op
//            co-op         coeur           coeur         coeur          cœur
//      cooperative          coop            coop          coop         coeur
//     co­operative         co-op           co-op   cooperative          coop
//             cœur   cooperative     cooperative  co­operative   cooperative
//            coeur  co­operative    co­operative          cœur  co­operative
open System
open System.Collections.Generic
open System.Globalization

// IComparer<String> implementation to perform string sort using an F# object expression.
let scompare = 
    { new IComparer<String> with
        member _.Compare(x, y) =
            CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort) }

let strings = [| "coop"; "co-op"; "cooperative"; "co\u00ADoperative"; "cœur"; "coeur" |]

// Perform a word sort using the current (en-US) culture.
let current = Array.copy strings
Array.Sort(current, StringComparer.CurrentCulture)

// Perform a word sort using the invariant culture.
let invariant = Array.copy strings
Array.Sort(invariant, StringComparer.InvariantCulture)

// Perform an ordinal sort.
let ordinal = Array.copy strings
Array.Sort(ordinal, StringComparer.Ordinal)

// Perform a string sort using the current culture.
let stringSort = Array.copy strings
Array.Sort(stringSort, scompare)

// Display array values
printfn "%13s %13s %15s %13s %13s\n" "Original" "Word Sort" "Invariant Word" "Ordinal Sort" "String Sort"
for i = 0 to strings.Length - 1 do
    printfn "%13s %13s %15s %13s %13s\n" strings[i] current[i] invariant[i] ordinal[i] stringSort[i]

// The example displays the following output:
//         Original     Word Sort  Invariant Word  Ordinal Sort   String Sort
//
//             coop          cœur            cœur         co-op         co-op
//            co-op         coeur           coeur         coeur          cœur
//      cooperative          coop            coop          coop         coeur
//     co­operative         co-op           co-op   cooperative          coop
//             cœur   cooperative     cooperative  co­operative   cooperative
//            coeur  co­operative    co­operative          cœur  co­operative
Imports System.Collections
Imports System.Collections.Generic
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim strings() As String = { "coop", "co-op", "cooperative", 
                                  "co" + ChrW(&h00AD) + "operative", 
                                  "cœur", "coeur" }

      ' Perform a word sort using the current (en-US) culture.
      Dim current(strings.Length - 1) As String  
      strings.CopyTo(current, 0) 
      Array.Sort(current, StringComparer.CurrentCulture)

      ' Perform a word sort using the invariant culture.
      Dim invariant(strings.Length - 1) As String
      strings.CopyTo(invariant, 0) 
      Array.Sort(invariant, StringComparer.InvariantCulture)

      ' Perform an ordinal sort.
      Dim ordinal(strings.Length - 1) As String
      strings.CopyTo(ordinal, 0) 
      Array.Sort(ordinal, StringComparer.Ordinal)

      ' Perform a string sort using the current culture.
      Dim stringSort(strings.Length - 1) As String
      strings.CopyTo(stringSort, 0) 
      Array.Sort(stringSort, new SCompare())

      ' Display array values
      Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}", 
                        "Original", "Word Sort", "Invariant Word", 
                        "Ordinal Sort", "String Sort")
      Console.WriteLine()
                                                      
      For ctr As Integer = 0 To strings.Length - 1
         Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}", 
                           strings(ctr), current(ctr), invariant(ctr), 
                           ordinal(ctr), stringSort(ctr))   
      Next                                  
   End Sub
End Module

' IComparer<String> implementation to perform string sort.
Friend Class SCompare : Implements IComparer(Of String)
   Public Function Compare(x As String, y As String) As Integer _
                   Implements IComparer(Of String).Compare
      Return CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort)
   End Function
End Class
' The example displays the following output:
'         Original     Word Sort  Invariant Word  Ordinal Sort   String Sort
'    
'             coop          cœur            cœur         co-op         co-op
'            co-op         coeur           coeur         coeur          cœur
'      cooperative          coop            coop          coop         coeur
'     co­operative         co-op           co-op   cooperative          coop
'             cœur   cooperative     cooperative  co­operative   cooperative
'            coeur  co­operative    co­operative          cœur  co­operative

提示

在内部,.NET 使用排序键来支持区域性敏感的字符串比较。 对于字符串中的每个字符,都赋予若干类排序权重,包括字母、大小写和变音符。 由类表示的 SortKey 排序键为特定字符串提供这些权重的存储库。 如果应用在同一组字符串上执行大量搜索或排序操作,可以通过为它使用的所有字符串生成和存储排序键来提高其性能。 需要排序或比较操作时,可以使用排序键而不是字符串。 有关更多信息,请参见 SortKey 类。

如果未指定字符串比较约定,则对字符串执行区分区域性、区分大小写的排序等 Array.Sort(Array) 排序方法。 以下示例演示了更改当前区域性如何影响数组中排序字符串的顺序。 它创建三个字符串的数组。 首先,它将 System.Threading.Thread.CurrentThread.CurrentCulture 属性设置为 en-US,并调用 Array.Sort(Array) 方法。 生成的排序顺序基于英语 (美国) 区域性的排序约定。 接着,此示例将 System.Threading.Thread.CurrentThread.CurrentCulture 属性设置为 da-DK 并再次调用 Array.Sort 方法。 请注意,最终排序顺序与使用 en-US 时的结果不一样,因为这次使用的是针对丹麦语(丹麦)的排序约定。

using System;
using System.Globalization;
using System.Threading;

public class ArraySort
{
   public static void Main(String[] args)
   {
      // Create and initialize a new array to store the strings.
      string[] stringArray = { "Apple", "Æble", "Zebra"};

      // Display the values of the array.
      Console.WriteLine( "The original string array:");
      PrintIndexAndValues(stringArray);

      // Set the CurrentCulture to "en-US".
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      // Sort the values of the array.
      Array.Sort(stringArray);

      // Display the values of the array.
      Console.WriteLine("After sorting for the culture \"en-US\":");
      PrintIndexAndValues(stringArray);

      // Set the CurrentCulture to "da-DK".
      Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
      // Sort the values of the Array.
      Array.Sort(stringArray);

      // Display the values of the array.
      Console.WriteLine("After sorting for the culture \"da-DK\":");
      PrintIndexAndValues(stringArray);
   }
   public static void PrintIndexAndValues(string[] myArray)
   {
      for (int i = myArray.GetLowerBound(0); i <=
            myArray.GetUpperBound(0); i++ )
         Console.WriteLine("[{0}]: {1}", i, myArray[i]);
      Console.WriteLine();
   }
}
// The example displays the following output:
//       The original string array:
//       [0]: Apple
//       [1]: Æble
//       [2]: Zebra
//
//       After sorting for the "en-US" culture:
//       [0]: Æble
//       [1]: Apple
//       [2]: Zebra
//
//       After sorting for the culture "da-DK":
//       [0]: Apple
//       [1]: Zebra
//       [2]: Æble
open System
open System.Globalization
open System.Threading

let printIndexAndValues (myArray: string[]) =
    for i = myArray.GetLowerBound 0 to myArray.GetUpperBound 0 do
        printfn $"[{i}]: {myArray[i]}" 
    printfn ""

// Create and initialize a new array to store the strings.
let stringArray = [| "Apple"; "Æble"; "Zebra" |]

// Display the values of the array.
printfn "The original string array:"
printIndexAndValues stringArray

// Set the CurrentCulture to "en-US".
Thread.CurrentThread.CurrentCulture <- CultureInfo "en-US"
// Sort the values of the array.
Array.Sort stringArray

// Display the values of the array.
printfn "After sorting for the culture \"en-US\":"
printIndexAndValues stringArray

// Set the CurrentCulture to "da-DK".
Thread.CurrentThread.CurrentCulture <- CultureInfo "da-DK"
// Sort the values of the Array.
Array.Sort stringArray

// Display the values of the array.
printfn "After sorting for the culture \"da-DK\":"
printIndexAndValues stringArray
// The example displays the following output:
//       The original string array:
//       [0]: Apple
//       [1]: Æble
//       [2]: Zebra
//
//       After sorting for the "en-US" culture:
//       [0]: Æble
//       [1]: Apple
//       [2]: Zebra
//
//       After sorting for the culture "da-DK":
//       [0]: Apple
//       [1]: Zebra
//       [2]: Æble
Imports System.Globalization
Imports System.IO
Imports System.Threading

Public Class TextToFile   
   Public Shared Sub Main()
      ' Creates and initializes a new array to store 
      ' these date/time objects.
      Dim stringArray() As String = { "Apple", "Æble", "Zebra"}
      
      ' Displays the values of the array.
      Console.WriteLine("The original string array:")
      PrintIndexAndValues(stringArray)
      
      ' Set the CurrentCulture to "en-US".
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      ' Sort the values of the Array.
      Array.Sort(stringArray)
      
      ' Display the values of the array.
      Console.WriteLine("After sorting for the ""en-US"" culture:")
      PrintIndexAndValues(stringArray)
      
      ' Set the CurrentCulture to "da-DK".
      Thread.CurrentThread.CurrentCulture = New CultureInfo("da-DK")
      ' Sort the values of the Array.
      Array.Sort(stringArray)
      
      ' Displays the values of the Array.
      Console.WriteLine("After sorting for the culture ""da-DK"":")
      PrintIndexAndValues(stringArray)
   End Sub

   Public Shared Sub PrintIndexAndValues(myArray() As String)
      For i As Integer = myArray.GetLowerBound(0) To myArray.GetUpperBound(0)
         Console.WriteLine("[{0}]: {1}", i, myArray(i))
      Next
      Console.WriteLine()
   End Sub 
End Class
' The example displays the following output:
'       The original string array:
'       [0]: Apple
'       [1]: Æble
'       [2]: Zebra
'       
'       After sorting for the "en-US" culture:
'       [0]: Æble
'       [1]: Apple
'       [2]: Zebra
'       
'       After sorting for the culture "da-DK":
'       [0]: Apple
'       [1]: Zebra
'       [2]: Æble

警告

如果比较字符串的主要用途是确定它们是否相等,则应调用该方法 String.Equals 。 通常,应用于 Equals 执行序号比较。 该方法 String.Compare 主要用于对字符串进行排序。

字符串搜索方法(如 String.StartsWithString.IndexOf)还可以执行区分区域性的序号字符串比较。 以下示例演示了使用 IndexOf 该方法进行序号和区分区域性的比较之间的差异。 当前区域性为英语的区分区域性的搜索 (美国) 将子字符串“oe”视为匹配连字“œ”。 由于软连字符 (U+00AD) 为零宽度字符,因此搜索会将软连字符视为等效 Empty 项,并在字符串开头找到匹配项。 另一方面,序号搜索在任一情况下都找不到匹配项。

using namespace System;

void FindInString(String^ s, String^ substring, StringComparison options);

void main()
{
   // Search for "oe" and "�u" in "�ufs" and "oeufs".
   String^ s1 = L"�ufs";
   String^ s2 = L"oeufs";
   FindInString(s1, "oe", StringComparison::CurrentCulture);
   FindInString(s1, "oe", StringComparison::Ordinal);
   FindInString(s2, "�u", StringComparison::CurrentCulture);
   FindInString(s2, "�u", StringComparison::Ordinal);
   Console::WriteLine();

   String^ s3 = L"co\x00ADoperative";
   FindInString(s3, L"\x00AD", StringComparison::CurrentCulture);
   FindInString(s3, L"\x00AD", StringComparison::Ordinal);
}

void FindInString(String^ s, String^ substring, StringComparison options)
{
   int result = s->IndexOf(substring, options);
   if (result != -1)
      Console::WriteLine("'{0}' found in {1} at position {2}", 
                        substring, s, result);
   else
      Console::WriteLine("'{0}' not found in {1}", 
                        substring, s);                                                  
}
// The example displays the following output:
//      'oe' found in oufs at position 0
//      'oe' not found in oufs
//      'ou' found in oeufs at position 0
//      'ou' not found in oeufs
//
//      '-' found in co-operative at position 0
//      '-' found in co-operative at position 2
using System;

public class Example
{
   public static void Main()
   {
      // Search for "oe" and "œu" in "œufs" and "oeufs".
      string s1 = "œufs";
      string s2 = "oeufs";
      FindInString(s1, "oe", StringComparison.CurrentCulture);
      FindInString(s1, "oe", StringComparison.Ordinal);
      FindInString(s2, "œu", StringComparison.CurrentCulture);
      FindInString(s2, "œu", StringComparison.Ordinal);
      Console.WriteLine();
      
      string s3 = "co\u00ADoperative";
      FindInString(s3, "\u00AD", StringComparison.CurrentCulture);
      FindInString(s3, "\u00AD", StringComparison.Ordinal);
   }

   private static void FindInString(string s, string substring, StringComparison options)
   {
      int result = s.IndexOf(substring, options);
      if (result != -1)
         Console.WriteLine("'{0}' found in {1} at position {2}", 
                           substring, s, result);
      else
         Console.WriteLine("'{0}' not found in {1}", 
                           substring, s);                                                  
   }
}
// The example displays the following output:
//       'oe' found in œufs at position 0
//       'oe' not found in œufs
//       'œu' found in oeufs at position 0
//       'œu' not found in oeufs
//       
//       '­' found in co­operative at position 0
//       '­' found in co­operative at position 2
open System

let findInString (s: string) (substring: string) (options: StringComparison) =
    let result = s.IndexOf(substring, options)
    if result <> -1 then
        printfn $"'{substring}' found in {s} at position {result}"
    else
        printfn $"'{substring}' not found in {s}"

// Search for "oe" and "œu" in "œufs" and "oeufs".
let s1 = "œufs"
let s2 = "oeufs"
findInString s1 "oe" StringComparison.CurrentCulture
findInString s1 "oe" StringComparison.Ordinal
findInString s2 "œu" StringComparison.CurrentCulture
findInString s2 "œu" StringComparison.Ordinal
printfn ""

let s3 = "co\u00ADoperative"
findInString s3 "\u00AD" StringComparison.CurrentCulture
findInString s3 "\u00AD" StringComparison.Ordinal

// The example displays the following output:
//       'oe' found in œufs at position 0
//       'oe' not found in œufs
//       'œu' found in oeufs at position 0
//       'œu' not found in oeufs
//
//       '­' found in co­operative at position 0
//       '­' found in co­operative at position 2
Module Example
   Public Sub Main()
      ' Search for "oe" and "œu" in "œufs" and "oeufs".
      Dim s1 As String = "œufs"
      Dim s2 As String = "oeufs"
      FindInString(s1, "oe", StringComparison.CurrentCulture)
      FindInString(s1, "oe", StringComparison.Ordinal)
      FindInString(s2, "œu", StringComparison.CurrentCulture)
      FindInString(s2, "œu", StringComparison.Ordinal)
      Console.WriteLine()
      
      Dim softHyphen As String = ChrW(&h00AD)
      Dim s3 As String = "co" + softHyphen + "operative"
      FindInString(s3, softHyphen, StringComparison.CurrentCulture)
      FindInString(s3, softHyphen, StringComparison.Ordinal)
   End Sub

   Private Sub FindInString(s As String, substring As String, 
                            options As StringComparison)
      Dim result As Integer = s.IndexOf(substring, options)
      If result <> -1
         Console.WriteLine("'{0}' found in {1} at position {2}", 
                           substring, s, result)
      Else
         Console.WriteLine("'{0}' not found in {1}", 
                           substring, s)
      End If                                                                          
   End Sub
End Module
' The example displays the following output:
'       'oe' found in œufs at position 0
'       'oe' not found in œufs
'       'œu' found in oeufs at position 0
'       'œu' not found in oeufs
'       
'       '­' found in co­operative at position 0
'       '­' found in co­operative at position 2

在字符串中搜索

字符串搜索方法(如 String.StartsWithString.IndexOf)还可以执行区分区域性的或序号字符串比较,以确定字符或子字符串是在指定字符串中找到的。

搜索单个字符(如方法)的类中的 String 搜索方法(如 IndexOf 方法)或一组字符之一(如 IndexOfAny 该方法)均执行序号搜索。 若要对字符执行区分区域性的搜索,必须调用 CompareInfo 方法,例如 CompareInfo.IndexOf(String, Char)CompareInfo.LastIndexOf(String, Char)。 请注意,使用序号和区分区域性的比较搜索字符的结果可能非常不同。 例如,搜索预编译的 Unicode 字符(如连字“Н” (U+00C6) 可能匹配其组件在正确序列中的任何匹配项,例如“AE” (U+041U+0045) ,具体取决于区域性。 以下示例说明了在搜索单个字符时的方法之间的差异String.IndexOf(Char)CompareInfo.IndexOf(String, Char)。 使用 en-US 区域性的约定时,在字符串“空中”中找到连字“æ” (U+00E6) ,但在使用 da-DK 区域性的约定或执行序号比较时,不会找到。

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      String[] cultureNames = { "da-DK", "en-US" };
      CompareInfo ci;
      String str = "aerial";
      Char ch = 'æ';  // U+00E6
      
      Console.Write("Ordinal comparison -- ");
      Console.WriteLine("Position of '{0}' in {1}: {2}", ch, str,
                        str.IndexOf(ch));
      
      foreach (var cultureName in cultureNames) {
         ci = CultureInfo.CreateSpecificCulture(cultureName).CompareInfo;
         Console.Write("{0} cultural comparison -- ", cultureName);
         Console.WriteLine("Position of '{0}' in {1}: {2}", ch, str,
                           ci.IndexOf(str, ch));
      }
   }
}
// The example displays the following output:
//       Ordinal comparison -- Position of 'æ' in aerial: -1
//       da-DK cultural comparison -- Position of 'æ' in aerial: -1
//       en-US cultural comparison -- Position of 'æ' in aerial: 0
open System.Globalization

let cultureNames = [| "da-DK"; "en-US" |]
let str = "aerial"
let ch = 'æ'  // U+00E6

printf "Ordinal comparison -- "
printfn $"Position of '{ch}' in {str}: {str.IndexOf ch}"
                  
for cultureName in cultureNames do
    let ci = CultureInfo.CreateSpecificCulture(cultureName).CompareInfo
    printf $"{cultureName} cultural comparison -- "
    printfn $"Position of '{ch}' in {str}: {ci.IndexOf(str, ch)}"
// The example displays the following output:
//       Ordinal comparison -- Position of 'æ' in aerial: -1
//       da-DK cultural comparison -- Position of 'æ' in aerial: -1
//       en-US cultural comparison -- Position of 'æ' in aerial: 0
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim cultureNames() As String = { "da-DK", "en-US" }
      Dim ci As CompareInfo
      Dim str As String = "aerial"
      Dim ch As Char = "æ"c  ' U+00E6
      
      Console.Write("Ordinal comparison -- ")
      Console.WriteLine("Position of '{0}' in {1}: {2}", ch, str,
                        str.IndexOf(ch))
      
      For Each cultureName In cultureNames
         ci = CultureInfo.CreateSpecificCulture(cultureName).CompareInfo
         Console.Write("{0} cultural comparison -- ", cultureName)
         Console.WriteLine("Position of '{0}' in {1}: {2}", ch, str,
                           ci.IndexOf(str, ch))
      Next
   End Sub
End Module
' The example displays the following output:
'       Ordinal comparison -- Position of 'æ' in aerial: -1
'       da-DK cultural comparison -- Position of 'æ' in aerial: -1
'       en-US cultural comparison -- Position of 'æ' in aerial: 0

另一方面,如果搜索选项不是按类型StringComparison参数显式指定搜索选项,String则搜索字符串而不是字符的类方法执行区分区域性的搜索。 唯一的例外是 Contains执行序号搜索。

针对相等性进行测试

String.Compare使用该方法确定排序顺序中的两个字符串之间的关系。 通常,这是一个区分区域性的操作。 相反,调用 String.Equals 该方法以测试相等性。 由于相等性测试通常将用户输入与某些已知字符串(例如有效的用户名、密码或文件系统路径)进行比较,因此通常是序号操作。

警告

可以通过调用 String.Compare 方法并确定返回值是否为零来测试相等性。 但是,不建议使用这种做法。 若要确定两个字符串是否相等,应调用方法的 String.Equals 重载之一。 要调用的首选重载是实例 Equals(String, StringComparison) 方法或静态 Equals(String, String, StringComparison) 方法,因为两种方法都包含 System.StringComparison 显式指定比较类型的参数。

以下示例说明了在应改用序号比较时执行区分区域性的相等性比较的危险。 在这种情况下,代码的目的是通过对 URL 开头的字符串“FILE://”执行不区分大小写的比较,禁止文件系统访问以“FILE://”或“file://”开头的 URL。 但是,如果使用以“file://”开头的 URL 上使用土耳其 (土耳其) 区域性执行区分区域性的比较,则相等比较将失败,因为与小写“i”等效的土耳其大写等效项是“ー”而不是“I”。 因此,无意中允许文件系统访问。 另一方面,如果执行序号比较,则相等比较成功,并且文件系统访问被拒绝。

using namespace System;
using namespace System::Globalization;
using namespace System::Threading;

bool TestForEquality(String^ str, StringComparison cmp);

void main()
{
   Thread::CurrentThread->CurrentCulture = CultureInfo::CreateSpecificCulture("tr-TR");      

   String^ filePath = "file://c:/notes.txt";

   Console::WriteLine("Culture-sensitive test for equality:");
   if (! TestForEquality(filePath, StringComparison::CurrentCultureIgnoreCase))
      Console::WriteLine("Access to {0} is allowed.", filePath);
   else
      Console::WriteLine("Access to {0} is not allowed.", filePath);

   Console::WriteLine("\nOrdinal test for equality:");
   if (! TestForEquality(filePath, StringComparison::OrdinalIgnoreCase))
      Console::WriteLine("Access to {0} is allowed.", filePath);
   else
      Console::WriteLine("Access to {0} is not allowed.", filePath);
}

bool TestForEquality(String^ str, StringComparison cmp)
{
      int position = str->IndexOf("://");
      if (position < 0) return false;

      String^ substring = str->Substring(0, position);  
      return substring->Equals("FILE", cmp);
}
// The example displays the following output: 
//       Culture-sensitive test for equality: 
//       Access to file://c:/notes.txt is allowed. 
//        
//       Ordinal test for equality: 
//       Access to file://c:/notes.txt is not allowed.
using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("tr-TR");      

      string filePath = "file://c:/notes.txt";
      
      Console.WriteLine("Culture-sensitive test for equality:");
      if (! TestForEquality(filePath, StringComparison.CurrentCultureIgnoreCase))
         Console.WriteLine("Access to {0} is allowed.", filePath);
      else
         Console.WriteLine("Access to {0} is not allowed.", filePath);
      
      Console.WriteLine("\nOrdinal test for equality:");
      if (! TestForEquality(filePath, StringComparison.OrdinalIgnoreCase))
         Console.WriteLine("Access to {0} is allowed.", filePath);
      else
         Console.WriteLine("Access to {0} is not allowed.", filePath);
   }

   private static bool TestForEquality(string str, StringComparison cmp)
   {
      int position = str.IndexOf("://");
      if (position < 0) return false;

      string substring = str.Substring(0, position);  
      return substring.Equals("FILE", cmp);
   }
}
// The example displays the following output:
//       Culture-sensitive test for equality:
//       Access to file://c:/notes.txt is allowed.
//       
//       Ordinal test for equality:
//       Access to file://c:/notes.txt is not allowed.
open System
open System.Globalization
open System.Threading

let testForEquality (str: string) (cmp: StringComparison) =
    let position = str.IndexOf "://"
    if position < 0 then false
    else
        let substring = str.Substring(0, position)
        substring.Equals("FILE", cmp)

Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "tr-TR"

let filePath = "file://c:/notes.txt"

printfn "Culture-sensitive test for equality:"
if not (testForEquality filePath StringComparison.CurrentCultureIgnoreCase) then
    printfn $"Access to {filePath} is allowed."
else
    printfn $"Access to {filePath} is not allowed."

printfn "\nOrdinal test for equality:"
if not (testForEquality filePath StringComparison.OrdinalIgnoreCase) then
    printfn $"Access to {filePath} is allowed."
else
    printfn $"Access to {filePath} is not allowed."

// The example displays the following output:
//       Culture-sensitive test for equality:
//       Access to file://c:/notes.txt is allowed.
//
//       Ordinal test for equality:
//       Access to file://c:/notes.txt is not allowed.
Imports System.Globalization
Imports System.Threading

Module Example
   Public Sub Main()
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("tr-TR")      

      Dim filePath As String = "file://c:/notes.txt"
      
      Console.WriteLine("Culture-sensitive test for equality:")
      If Not TestForEquality(filePath, StringComparison.CurrentCultureIgnoreCase) Then
         Console.WriteLine("Access to {0} is allowed.", filePath)
      Else
         Console.WriteLine("Access to {0} is not allowed.", filePath)
      End If       
      Console.WriteLine()
      
      Console.WriteLine("Ordinal test for equality:")
      If Not TestForEquality(filePath, StringComparison.OrdinalIgnoreCase) Then
         Console.WriteLine("Access to {0} is allowed.", filePath)
      Else
         Console.WriteLine("Access to {0} is not allowed.", filePath)
      End If       
   End Sub
   
   Private Function TestForEquality(str As String, cmp As StringComparison) As Boolean
      Dim position As Integer = str.IndexOf("://")
      If position < 0 Then Return False

      Dim substring As String = str.Substring(0, position)  
      Return substring.Equals("FILE", cmp)
   End Function
End Module
' The example displays the following output:
'       Culture-sensitive test for equality:
'       Access to file://c:/notes.txt is allowed.
'       
'       Ordinal test for equality:
'       Access to file://c:/notes.txt is not allowed.

标准化

某些 Unicode 字符具有多个表示形式。 例如,以下任何代码点都可以表示字母“ắ”:

  • U+1EAF

  • U+0103 U+0301

  • U+0061 U+0306 U+0301

单个字符的多个表示形式使搜索、排序、匹配和其他字符串操作复杂化。

Unicode 标准定义一个名为规范化的过程,它为其任何等效的二进制表示形式返回 Unicode 字符的一个二进制表示形式。 规范化可以使用遵循不同规则的多个算法(称为规范化形式)。 .NET 支持 Unicode 规范化形式 C、D、KC 和 KD。 当字符串规范化为同一规范化形式时,可以使用序号比较来比较它们。

序号比较是对每个字符串中对应 Char 对象的 Unicode 标量值的二进制比较。 该 String 类包含许多可以执行序号比较的方法,包括以下内容:

可以通过调用 String.IsNormalized() 方法来确定字符串是否规范化为规范化形式 C,也可以调用 String.IsNormalized(NormalizationForm) 该方法来确定字符串是否规范化为指定的规范化形式。 还可以调用 String.Normalize() 方法将字符串转换为规范化表单 C,也可以调用 String.Normalize(NormalizationForm) 该方法将字符串转换为指定的规范化形式。 有关规范化和比较字符串的分步信息,请参阅 Normalize()Normalize(NormalizationForm) 方法。

下面的简单示例演示字符串规范化。 它在三个不同的字符串中以三种不同的方式定义字母“ố”,并使用序号比较来确定每个字符串与其他两个字符串不同。 然后,它将每个字符串转换为受支持的规范化形式,并再次执行指定规范化形式的每个字符串的序号比较。 在每个情况下,第二个相等测试显示字符串相等。

using namespace System;
using namespace System::Globalization;
using namespace System::IO;
using namespace System::Text;

public ref class Example
{
private:
   StreamWriter^ sw;

   void TestForEquality(... array<String^>^  words)
   {
      for (int ctr = 0; ctr <= words->Length - 2; ctr++)
         for (int ctr2 = ctr + 1; ctr2 <= words->Length - 1; ctr2++) 
            sw->WriteLine("{0} ({1}) = {2} ({3}): {4}", 
                         words[ctr], ShowBytes(words[ctr]),
                         words[ctr2], ShowBytes(words[ctr2]),
                         words[ctr]->Equals(words[ctr2], StringComparison::Ordinal));
   }

   String^ ShowBytes(String^ str)
   {
      String^ result = nullptr;
      for each (Char ch in str)
         result += String::Format("{0} ", Convert::ToUInt16(ch).ToString("X4")); 
      return result->Trim();            
   } 

   array<String^>^ NormalizeStrings(NormalizationForm nf, ... array<String^>^ words)
   {
      for (int ctr = 0; ctr < words->Length; ctr++)
         if (! words[ctr]->IsNormalized(nf))
            words[ctr] = words[ctr]->Normalize(nf); 
      return words;   
   }

public: 
   void Execute()
   {
      sw = gcnew StreamWriter(".\\TestNorm1.txt");

      // Define three versions of the same word.  
      String^ s1 = L"sống";        // create word with U+1ED1 
      String^ s2 = L"s\x00F4\x0301ng";
      String^ s3 = L"so\x0302\x0301ng";

      TestForEquality(s1, s2, s3);      
      sw->WriteLine();

      // Normalize and compare strings using each normalization form. 
      for each (String^ formName in Enum::GetNames(NormalizationForm::typeid))
      {
         sw->WriteLine("Normalization {0}:\n", formName); 
         NormalizationForm nf = (NormalizationForm) Enum::Parse(NormalizationForm::typeid, formName);
         array<String^>^ sn = NormalizeStrings(nf, s1, s2, s3 );
         TestForEquality(sn);           
         sw->WriteLine("\n");                                        
      }

      sw->Close(); 
   }
};

void main()
{
   Example^ ex = gcnew Example();
   ex->Execute();
}
// The example produces the following output:
// The example displays the following output: 
//       sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False 
//       sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False 
//       sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False 
//        
//       Normalization FormC: 
//        
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True 
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True 
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True 
//        
//        
//       Normalization FormD: 
//        
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True 
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True 
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True 
//        
//        
//       Normalization FormKC: 
//        
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True 
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True 
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True 
//        
//        
//       Normalization FormKD: 
//        
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True 
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True 
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
using System;
using System.Globalization;
using System.IO;
using System.Text;

public class Example
{
   private static StreamWriter sw;
   
   public static void Main()
   {
      sw = new StreamWriter(@".\TestNorm1.txt");

      // Define three versions of the same word. 
      string s1 = "sống";        // create word with U+1ED1
      string s2 = "s\u00F4\u0301ng";
      string s3 = "so\u0302\u0301ng";

      TestForEquality(s1, s2, s3);      
      sw.WriteLine();

      // Normalize and compare strings using each normalization form.
      foreach (string formName in Enum.GetNames(typeof(NormalizationForm)))
      {
         sw.WriteLine("Normalization {0}:\n", formName); 
         NormalizationForm nf = (NormalizationForm) Enum.Parse(typeof(NormalizationForm), formName);
         string[] sn = NormalizeStrings(nf, s1, s2, s3);
         TestForEquality(sn);           
         sw.WriteLine("\n");                                        
      }
      
      sw.Close();   
   }

   private static void TestForEquality(params string[] words)
   {
      for (int ctr = 0; ctr <= words.Length - 2; ctr++)
         for (int ctr2 = ctr + 1; ctr2 <= words.Length - 1; ctr2++) 
            sw.WriteLine("{0} ({1}) = {2} ({3}): {4}", 
                         words[ctr], ShowBytes(words[ctr]),
                         words[ctr2], ShowBytes(words[ctr2]),
                         words[ctr].Equals(words[ctr2], StringComparison.Ordinal));
   }

   private static string ShowBytes(string str)
   {
      string result = null;
      foreach (var ch in str)
         result += $"{(ushort)ch:X4} ";
      return result.Trim();            
   } 
   
   private static string[] NormalizeStrings(NormalizationForm nf, params string[] words)
   {
      for (int ctr = 0; ctr < words.Length; ctr++)
         if (! words[ctr].IsNormalized(nf))
            words[ctr] = words[ctr].Normalize(nf); 
      return words;   
   }
}
// The example displays the following output:
//       sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
//       sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//       sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//       
//       Normalization FormC:
//       
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       
//       
//       Normalization FormD:
//       
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       
//       
//       Normalization FormKC:
//       
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       
//       
//       Normalization FormKD:
//       
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
open System
open System.IO
open System.Text

do
    use sw = new StreamWriter(@".\TestNorm1.txt")

    let showBytes (str: string) =
        let mutable result = ""
        for ch in str do
            result <- result + $"{uint16 ch:X4} "
        result.Trim()
    
    let testForEquality (words: string[]) =
        for ctr = 0 to words.Length - 2 do
            for ctr2 = ctr + 1 to words.Length - 1 do
                sw.WriteLine("{0} ({1}) = {2} ({3}): {4}",
                            words[ctr], showBytes(words[ctr]),
                            words[ctr2], showBytes(words[ctr2]),
                            words[ctr].Equals(words[ctr2], StringComparison.Ordinal))

    let normalizeStrings nf (words: string[]) =
        for i = 0 to words.Length - 1 do
            if not (words[i].IsNormalized nf) then
                words[i] <- words[i].Normalize nf
        words

    // Define three versions of the same word.
    let s1 = "sống"        // create word with U+1ED1
    let s2 = "s\u00F4\u0301ng"
    let s3 = "so\u0302\u0301ng"

    testForEquality [| s1; s2; s3 |]
    sw.WriteLine()

    // Normalize and compare strings using each normalization form.
    for formName in Enum.GetNames typeof<NormalizationForm> do
        sw.WriteLine("Normalization {0}:\n", formName)
        let nf = Enum.Parse(typeof<NormalizationForm>, formName) :?> NormalizationForm
        let sn = normalizeStrings nf [| s1; s2; s3|]
        testForEquality sn
        sw.WriteLine "\n"

// The example displays the following output:
//       sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
//       sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//       sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//
//       Normalization FormC:
//
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
//       Normalization FormD:
//
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//
//
//       Normalization FormKC:
//
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
//       Normalization FormKD:
//
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
Imports System.Globalization
Imports System.IO
Imports System.Text

Module Example
   Private sw As StreamWriter
       
   Public Sub Main()
      sw = New StreamWriter(".\TestNorm1.txt")

      ' Define three versions of the same word. 
      Dim s1 As String = "sống"        ' create word with U+1ED1
      Dim s2 AS String = "s" + ChrW(&h00F4) + ChrW(&h0301) + "ng"
      Dim s3 As String = "so" + ChrW(&h0302) + ChrW(&h0301) + "ng"

      TestForEquality(s1, s2, s3)      
      sw.WriteLine()

      ' Normalize and compare strings using each normalization form.
      For Each formName In [Enum].GetNames(GetType(NormalizationForm))
         sw.WriteLine("Normalization {0}:", formName) 
         Dim nf As NormalizationForm = CType([Enum].Parse(GetType(NormalizationForm), formName),  
                                             NormalizationForm)
         Dim sn() As String = NormalizeStrings(nf, s1, s2, s3)
         TestForEquality(sn)           
         sw.WriteLine(vbCrLf)                                        
      Next
      
      sw.Close()   
   End Sub

   Private Sub TestForEquality(ParamArray words As String())
      For ctr As Integer = 0 To words.Length - 2
         For ctr2 As Integer = ctr + 1 To words.Length - 1 
            sw.WriteLine("{0} ({1}) = {2} ({3}): {4}", 
                         words(ctr), ShowBytes(words(ctr)),
                         words(ctr2), ShowBytes(words(ctr2)),
                         words(ctr).Equals(words(ctr2), StringComparison.Ordinal))
         Next                
      Next   
   End Sub

   Private Function ShowBytes(str As String) As String
      Dim result As String = Nothing
      For Each ch In str
         result += String.Format("{0} ", Convert.ToUInt16(ch).ToString("X4")) 
      Next
      Return result.Trim()            
   End Function  
   
   Private Function NormalizeStrings(nf As NormalizationForm, ParamArray words() As String) As String()
      For ctr As Integer = 0 To words.Length - 1
         If Not words(ctr).IsNormalized(nf) Then
            words(ctr) = words(ctr).Normalize(nf)
         End If    
      Next
      Return words   
   End Function
End Module
' The example displays the following output:
'       sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
'       sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
'       sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
'       
'       Normalization FormC:
'       
'       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'       
'       
'       Normalization FormD:
'       
'       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
'       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
'       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
'       
'       
'       Normalization FormKC:
'       
'       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'       sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
'       
'       
'       Normalization FormKD:
'       
'       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
'       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
'       sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True

有关规范化和规范化表单的详细信息,请参阅 System.Text.NormalizationForm,以及 Unicode 标准附件 #15:unicode.org 网站上的 Unicode 规范化窗体规范化常见问题解答

按类别划分的字符串操作

String 类提供用于比较字符串、测试字符串是否相等、查找字符串或子字符串、修改字符串、从字符串中提取子字符串、组合字符串、格式值、复制字符串和规范化字符串的成员。

比较字符串

可以使用以下 String 方法比较字符串来确定字符串在排序顺序中的相对位置:

  • Compare 返回一个整数,指示一个字符串与排序顺序中的第二个字符串之间的关系。

  • CompareOrdinal 返回一个整数,该整数指示一个字符串与其代码点的比较,将一个字符串与第二个字符串的关系。

  • CompareTo 返回一个整数,该整数指示当前字符串实例与排序顺序中的第二个字符串之间的关系。 该方法 CompareTo(String) 为类提供 IComparableIComparable<T> 实现 String

测试字符串的相等性

调用该方法 Equals 以确定两个字符串是否相等。 使用实例 Equals(String, String, StringComparison) 和静态 Equals(String, StringComparison) 重载可以指定比较是区分区域性还是序号,以及是否考虑或忽略事例。 大多数相等测试都是序号,并且确定对系统资源 ((如文件系统对象) )的访问权限的相等性比较应始终为序号。

查找字符串中的字符

String 类包括两种类型的搜索方法:

警告

如果要搜索特定模式而不是特定子字符串的字符串,则应使用正则表达式。 有关详细信息,请参阅 .NET 正则表达式

修改字符串

String 类包括以下方法,这些方法似乎修改字符串的值:

  • Insert 将字符串插入当前 String 实例。

  • PadLeft 在字符串开头插入指定字符的一个或多个匹配项。

  • PadRight 在字符串末尾插入指定字符的一个或多个匹配项。

  • Remove 从当前 String 实例中删除子字符串。

  • Replace 将子字符串替换为当前 String 实例中的另一个子字符串。

  • ToLower 并将 ToLowerInvariant 字符串中的所有字符转换为小写。

  • ToUpper 并将 ToUpperInvariant 字符串中的所有字符转换为大写。

  • Trim 从字符串的开头和结尾删除字符的所有匹配项。

  • TrimEnd 从字符串末尾删除字符的所有匹配项。

  • TrimStart 从字符串开头删除字符的所有匹配项。

重要

所有字符串修改方法都返回一个新 String 对象。 它们不会修改当前实例的值。

从字符串中提取子字符串

该方法 String.Split 将单个字符串分隔成多个字符串。 此方法的重载允许指定多个分隔符、限制方法提取的子字符串数、从子字符串中剪裁空格,以及指定是否在返回的字符串中包含分隔符) 时发生的空字符串 (。

合并字符串

以下 String 方法可用于字符串串联:

  • Concat 将一个或多个子字符串合并到单个字符串中。

  • Join 将一个或多个子字符串串联到单个元素中,并在每个子字符串之间添加分隔符。

设置值格式

该方法 String.Format 使用复合格式设置功能将字符串中的一个或多个占位符替换为某些对象或值的字符串表示形式。 该方法 Format 通常用于执行以下操作:

  • 在字符串中嵌入数值的字符串表示形式。

  • 在字符串中嵌入日期和时间值的字符串表示形式。

  • 在字符串中嵌入枚举值的字符串表示形式。

  • 在字符串中嵌入支持 IFormattable 接口的某些对象的字符串表示形式。

  • 在较大字符串的字段中右对齐或左对齐子字符串。

有关设置操作和示例的详细信息,请参阅 Format 重载摘要。

复制字符串

可以调用以下 String 方法来创建字符串的副本:

  • Clone 返回对现有 String 对象的引用。

  • Copy 创建现有字符串的副本。

  • CopyTo 将字符串的一部分复制到字符数组。

规范化字符串

在 Unicode 中,单个字符可以有多个代码点。 规范化将这些等效字符转换为相同的二进制表示形式。 该方法 String.Normalize 执行规范化,该方法 String.IsNormalized 确定字符串是否规范化。

有关详细信息和示例,请参阅本主题前面的 规范化 部分。

构造函数

String(Char*)

String 类的新实例初始化为由指向 Unicode 字符数组的指定指针指示的值。

String(Char*, Int32, Int32)

String 类的新实例初始化为由指向 Unicode 字符数组的指定指针指示的值、该数组内的起始字符位置和一个长度指示的值。

String(Char, Int32)

String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值。

String(Char[])

String 类的新实例初始化为指定字符数组中指示的 Unicode 字符。

String(Char[], Int32, Int32)

String 类的新实例初始化为由 Unicode 字符数组、该数组内的起始字符位置和一个长度指示的值。

String(ReadOnlySpan<Char>)

String 类的新实例初始化为指定只读范围中指示的 Unicode 字符。

String(SByte*)

String 类的新实例初始化为由指向 8 位有符号整数数组的指针指示的值。

String(SByte*, Int32, Int32)

String 类的新实例初始化为由指向 8 位有符号整数数组的指定指针、该数组内的起始位置和一个长度指示的值。

String(SByte*, Int32, Int32, Encoding)

String 的新实例初始化为由指向 8 位有符号整数数组的指定指针、该数组内的起始位置、长度以及 Encoding 对象指示的值。

字段

Empty

表示空字符串。 此字段为只读。

属性

Chars[Int32]

获取当前 Char 对象中位于指定位置的 String 对象。

Length

获取当前 String 对象中的字符数。

方法

Clone()

返回对此 String实例的引用。

Compare(String, Int32, String, Int32, Int32)

比较两个指定的 String 对象的子字符串,并返回一个指示二者在排序顺序中的相对位置的整数。

Compare(String, Int32, String, Int32, Int32, Boolean)

比较两个指定的 String 对象的子字符串(忽略或考虑其大小写),并返回一个整数,指示二者在排序顺序中的相对位置。

Compare(String, Int32, String, Int32, Int32, Boolean, CultureInfo)

比较两个指定的 String 对象(其中忽略或考虑其大小写,并使用区域性特定的信息干预比较),并返回一个整数,指示二者在排序顺序中的相对位置。

Compare(String, Int32, String, Int32, Int32, CultureInfo, CompareOptions)

对两个指定 String 对象的子字符串进行比较,使用指定的比较选项和区域性特定的信息来影响比较,并返回一个整数,该整数指示这两个子字符串在排序顺序中的关系。

Compare(String, Int32, String, Int32, Int32, StringComparison)

使用指定的规则比较两个指定的 String 对象的子字符串,并返回一个整数,指示二者在排序顺序中的相对位置。

Compare(String, String)

比较两个指定的 String 对象,并返回一个指示二者在排序顺序中的相对位置的整数。

Compare(String, String, Boolean)

比较两个指定的 String 对象(其中忽略或考虑其大小写),并返回一个整数,指示二者在排序顺序中的相对位置。

Compare(String, String, Boolean, CultureInfo)

比较两个指定的 String 对象(其中忽略或考虑其大小写,并使用区域性特定的信息干预比较),并返回一个整数,指示二者在排序顺序中的相对位置。

Compare(String, String, CultureInfo, CompareOptions)

对两个指定的 String 对象进行比较,使用指定的比较选项和区域性特定的信息来影响比较,并返回一个整数,该整数指示这两个字符串在排序顺序中的关系。

Compare(String, String, StringComparison)

使用指定的规则比较两个指定的 String 对象,并返回一个整数,指示二者在排序顺序中的相对位置。

CompareOrdinal(String, Int32, String, Int32, Int32)

通过计算每个子字符串中相应 String 对象的数值来比较两个指定的 Char 对象的子字符串。

CompareOrdinal(String, String)

通过计算每个字符串中相应 String 对象的数值来比较两个指定的 Char 对象。

CompareTo(Object)

将此实例与指定的 Object 进行比较,并指示此实例在排序顺序中是位于指定的 Object 之前、之后还是与其出现在同一位置。

CompareTo(String)

将此实例与指定的 String 对象进行比较,并指示此实例在排序顺序中是位于指定的字符串之前、之后还是与其出现在同一位置。

Concat(IEnumerable<String>)

串联类型为 IEnumerable<T>String 构造集合的成员。

Concat(Object)

创建指定对象的字符串表示形式。

Concat(Object, Object)

连接两个指定对象的字符串表示形式。

Concat(Object, Object, Object)

连接三个指定对象的字符串表示形式。

Concat(Object, Object, Object, Object)

将四个指定对象的字符串表示形式与可选变量长度参数列表中指定的任何对象串联起来。

Concat(Object[])

连接指定 Object 数组中的元素的字符串表示形式。

Concat(ReadOnlySpan<Char>, ReadOnlySpan<Char>)

连接两个指定的只读字符范围的字符串表示形式。

Concat(ReadOnlySpan<Char>, ReadOnlySpan<Char>, ReadOnlySpan<Char>)

连接三个指定的只读字符范围的字符串表示形式。

Concat(ReadOnlySpan<Char>, ReadOnlySpan<Char>, ReadOnlySpan<Char>, ReadOnlySpan<Char>)

连接四个指定的只读字符范围的字符串表示形式。

Concat(String, String)

连接 String 的两个指定实例。

Concat(String, String, String)

连接 String 的三个指定实例。

Concat(String, String, String, String)

连接 String 的四个指定实例。

Concat(String[])

连接指定的 String 数组的元素。

Concat<T>(IEnumerable<T>)

串联 IEnumerable<T> 实现的成员。

Contains(Char)

返回一个值,该值指示指定的字符是否出现在此字符串中。

Contains(Char, StringComparison)

使用指定的比较规则返回一个值,该值指示指定的字符是否出现在此字符串中。

Contains(String)

返回一个值,该值指示指定的子串是否出现在此字符串中。

Contains(String, StringComparison)

使用指定的比较规则返回一个值,该值指示指定的字符串是否出现在此字符串中。

Copy(String)
已过时。

创建一个与指定的 String 具有相同值的 String 的新实例。

CopyTo(Int32, Char[], Int32, Int32)

将指定数目的字符从此实例中的指定位置复制到 Unicode 字符数组中的指定位置。

CopyTo(Span<Char>)

将此字符串的内容复制到目标范围。

Create(IFormatProvider, DefaultInterpolatedStringHandler)

通过使用指定的提供程序来控制指定内插字符串的格式,创建一个新字符串。

Create(IFormatProvider, Span<Char>, DefaultInterpolatedStringHandler)

通过使用指定的提供程序来控制指定内插字符串的格式,创建一个新字符串。

Create<TState>(Int32, TState, SpanAction<Char,TState>)

创建一个具有特定长度的新字符串,并在创建后使用指定的回叫对其进行初始化。

EndsWith(Char)

确定此字符串实例的结尾是否与指定的字符匹配。

EndsWith(String)

确定此字符串实例的结尾是否与指定的字符串匹配。

EndsWith(String, Boolean, CultureInfo)

确定在使用指定的区域性进行比较时此字符串实例的结尾是否与指定的字符串匹配。

EndsWith(String, StringComparison)

确定使用指定的比较选项进行比较时此字符串实例的结尾是否与指定的字符串匹配。

EnumerateRunes()

从此字符串返回 Rune 的枚举。

Equals(Object)

确定此实例是否与指定的对象(也必须是 String 对象)具有相同的值。

Equals(String)

确定此实例是否与另一个指定的 String 对象具有相同的值。

Equals(String, String)

确定两个指定的 String 对象是否具有相同的值。

Equals(String, String, StringComparison)

确定两个指定的 String 对象是否具有相同的值。 参数指定区域性、大小写以及比较所用的排序规则。

Equals(String, StringComparison)

确定此字符串是否与另一个指定的 String 对象具有相同的值。 参数指定区域性、大小写以及比较所用的排序规则。

Format(IFormatProvider, String, Object)

将指定字符串中的一个或多个格式项替换为对应对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

Format(IFormatProvider, String, Object, Object)

将字符串中的格式项替换为两个指定对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

Format(IFormatProvider, String, Object, Object, Object)

将字符串中的格式项替换为三个指定对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

Format(IFormatProvider, String, Object[])

将字符串中的格式项替换为指定数组中相应对象的字符串表示形式。 参数提供区域性特定的格式设置信息。

Format(String, Object)

将字符串中的一个或多个格式项替换为指定对象的字符串表示形式。

Format(String, Object, Object)

将字符串中的格式项替换为两个指定对象的字符串表示形式。

Format(String, Object, Object, Object)

将字符串中的格式项替换为三个指定对象的字符串表示形式。

Format(String, Object[])

将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。

GetEnumerator()

检索一个可以循环访问此字符串中的每个字符的对象。

GetHashCode()

返回该字符串的哈希代码。

GetHashCode(ReadOnlySpan<Char>)

返回所提供的只读字符范围的哈希代码。

GetHashCode(ReadOnlySpan<Char>, StringComparison)

使用指定的规则返回所提供的只读字符范围的哈希代码。

GetHashCode(StringComparison)

使用指定的规则返回此字符串的哈希代码。

GetPinnableReference()

返回对索引 0 处字符串的元素的引用。

此方法旨在支持 .NET 编译器,不应由用户代码调用。

GetType()

获取当前实例的 Type

(继承自 Object)
GetTypeCode()

返回 String 类的 TypeCode

IndexOf(Char)

报告指定 Unicode 字符在此字符串中的第一个匹配项的从零开始的索引。

IndexOf(Char, Int32)

报告指定 Unicode 字符在此字符串中的第一个匹配项的从零开始的索引。 该搜索从指定字符位置开始。

IndexOf(Char, Int32, Int32)

报告指定字符在此实例中的第一个匹配项的从零开始的索引。 搜索从指定字符位置开始,并检查指定数量的字符位置。

IndexOf(Char, StringComparison)

报告指定 Unicode 字符在此字符串中的第一个匹配项的从零开始的索引。 一个参数指定要用于指定字符的搜索类型。

IndexOf(String)

报告指定字符串在此实例中的第一个匹配项的从零开始的索引。

IndexOf(String, Int32)

报告指定字符串在此实例中的第一个匹配项的从零开始的索引。 该搜索从指定字符位置开始。

IndexOf(String, Int32, Int32)

报告指定字符串在此实例中的第一个匹配项的从零开始的索引。 搜索从指定字符位置开始,并检查指定数量的字符位置。

IndexOf(String, Int32, Int32, StringComparison)

报告指定的字符串在当前 String 对象中的第一个匹配项的从零开始的索引。 参数指定当前字符串中的起始搜索位置、要搜索的当前字符串中的字符数量,以及要用于指定字符串的搜索类型。

IndexOf(String, Int32, StringComparison)

报告指定的字符串在当前 String 对象中的第一个匹配项的从零开始的索引。 参数指定当前字符串中的起始搜索位置以及用于指定字符串的搜索类型。

IndexOf(String, StringComparison)

报告指定的字符串在当前 String 对象中的第一个匹配项的从零开始的索引。 一个参数指定要用于指定字符串的搜索类型。

IndexOfAny(Char[])

报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的从零开始的索引。

IndexOfAny(Char[], Int32)

报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的从零开始的索引。 该搜索从指定字符位置开始。

IndexOfAny(Char[], Int32, Int32)

报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的从零开始的索引。 搜索从指定字符位置开始,并检查指定数量的字符位置。

Insert(Int32, String)

返回一个新的字符串,在此实例中的指定的索引位置插入指定的字符串。

Intern(String)

检索系统对指定 String 的引用。

IsInterned(String)

检索对指定 String 的引用。

IsNormalized()

指示此字符串是否符合 Unicode 范式 C。

IsNormalized(NormalizationForm)

指示此字符串是否符合指定的 Unicode 范式。

IsNullOrEmpty(String)

指示指定的字符串是 null 还是空字符串 ("")。

IsNullOrWhiteSpace(String)

指示指定的字符串是 null、空还是仅由空白字符组成。

Join(Char, Object[])

连接对象数组的字符串表示形式,其中在每个成员之间使用指定的分隔符。

Join(Char, String[])

连接字符串数组,其中在每个成员之间使用指定的分隔符。

Join(Char, String[], Int32, Int32)

连接字符串数组,其中在每个成员之间使用指定的分隔符,并且从位于 startIndex 位置的 value 中的元素开始,并连接多达 count 个元素。

Join(String, IEnumerable<String>)

串联类型为 IEnumerable<T>String 构造集合的成员,其中在每个成员之间使用指定的分隔符。

Join(String, Object[])

串联对象数组的各个元素,其中在每个元素之间使用指定的分隔符。

Join(String, String[])

串联字符串数组的所有元素,其中在每个元素之间使用指定的分隔符。

Join(String, String[], Int32, Int32)

串联字符串数组的指定元素,其中在每个元素之间使用指定的分隔符。

Join<T>(Char, IEnumerable<T>)

串联集合的成员,其中在每个成员之间使用指定的分隔符。

Join<T>(String, IEnumerable<T>)

串联集合的成员,其中在每个成员之间使用指定的分隔符。

LastIndexOf(Char)

报告指定 Unicode 字符在此实例中的最后一个匹配项的从零开始的索引的位置。

LastIndexOf(Char, Int32)

报告指定 Unicode 字符在此实例中的最后一个匹配项的从零开始的索引的位置。 在指定的字符位置开始和在向后的右边该字符串的开头处理的搜索。

LastIndexOf(Char, Int32, Int32)

报告指定的 Unicode 字符在此实例内的子字符串中的最后一个匹配项的从零开始的索引的位置。 搜索在指定字符位置的数目的字符串开始时,开始指定字符和其后面的位置。

LastIndexOf(String)

报告指定字符串在此实例中的最后一个匹配项的从零开始的索引的位置。

LastIndexOf(String, Int32)

报告指定字符串在此实例中的最后一个匹配项的从零开始的索引的位置。 在指定的字符位置开始和在向后的右边该字符串的开头处理的搜索。

LastIndexOf(String, Int32, Int32)

报告指定字符串在此实例中的最后一个匹配项的从零开始的索引的位置。 搜索在指定字符位置的数目的字符串开始时,开始指定字符和其后面的位置。

LastIndexOf(String, Int32, Int32, StringComparison)

报告指定字符串在此实例中的最后一个匹配项的从零开始的索引的位置。 搜索在所指定的字符位置的数目的字符串开始时,开始指定字符和其后面的位置。 一个参数指定要执行搜索指定字符串的比较类型。

LastIndexOf(String, Int32, StringComparison)

报告指定字符串在当前 String 对象中最后一个匹配项的从零开始的索引。 在指定的字符位置开始和在向后的右边该字符串的开头处理的搜索。 一个参数指定要执行搜索指定字符串的比较类型。

LastIndexOf(String, StringComparison)

报告指定字符串在当前 String 对象中最后一个匹配项的从零开始的索引。 一个参数指定要用于指定字符串的搜索类型。

LastIndexOfAny(Char[])

报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的从零开始的索引的位置。

LastIndexOfAny(Char[], Int32)

报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的从零开始的索引的位置。 在指定的字符位置开始和在向后的右边该字符串的开头处理的搜索。

LastIndexOfAny(Char[], Int32, Int32)

报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的从零开始的索引的位置。 搜索在指定字符位置的数目的字符串开始时,开始指定字符和其后面的位置。

MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
Normalize()

返回一个新字符串,其文本值与此字符串相同,但其二进制表示形式符合 Unicode 范式 C。

Normalize(NormalizationForm)

返回一个新字符串,其文本值与此字符串相同,但其二进制表示形式符合指定的 Unicode 范式。

PadLeft(Int32)

返回一个新字符串,该字符串通过在此实例中的字符左侧填充空格来达到指定的总长度,从而实现右对齐。

PadLeft(Int32, Char)

返回一个新字符串,该字符串通过在此实例中的字符左侧填充指定的 Unicode 字符来达到指定的总长度,从而使这些字符右对齐。

PadRight(Int32)

返回一个新字符串,该字符串通过在此字符串中的字符右侧填充空格来达到指定的总长度,从而使这些字符左对齐。

PadRight(Int32, Char)

返回一个新字符串,该字符串通过在此字符串中的字符右侧填充指定的 Unicode 字符来达到指定的总长度,从而使这些字符左对齐。

Remove(Int32)

返回当前实例中从指定位置到最后位置的所有以删除的字符的新字符串。

Remove(Int32, Int32)

返回指定数量字符在当前这个实例起始点在已删除的指定的位置的新字符串。

Replace(Char, Char)

返回一个新字符串,其中此实例中出现的所有指定 Unicode 字符都替换为另一个指定的 Unicode 字符。

Replace(String, String)

返回一个新字符串,其中当前实例中出现的所有指定字符串都替换为另一个指定的字符串。

Replace(String, String, Boolean, CultureInfo)

返回一个新字符串,其中当前实例中出现的所有指定字符串都使用提供的区域性和区分大小写属性替换为另一个指定的字符串。

Replace(String, String, StringComparison)

返回一个新字符串,其中当前实例中出现的所有指定字符串都使用提供的比较类型替换为另一个指定的字符串。

ReplaceLineEndings()

将当前字符串中的所有换行序列替换为 NewLine

ReplaceLineEndings(String)

将当前字符串中的所有换行序列替换为 replacementText

Split(Char, Int32, StringSplitOptions)

基于指定的分隔字符和(可选)选项将字符串拆分为最大数量的子字符串。 根据提供的字符分隔符将字符串拆分为最大数量的子字符串,可以选择忽略结果中的空子字符串。

Split(Char, StringSplitOptions)

根据指定的分隔字符将字符串拆分为子字符串,以及(可选)选项。

Split(Char[])

根据指定的分隔字符将字符串拆分为子字符串。

Split(Char[], Int32)

根据指定的分隔字符将字符串拆分为最大子字符串数。

Split(Char[], Int32, StringSplitOptions)

基于指定的分隔字符和(可选)选项将字符串拆分为最大数量的子字符串。

Split(Char[], StringSplitOptions)

根据指定的分隔字符和选项将字符串拆分为子字符串。

Split(String, Int32, StringSplitOptions)

基于指定的分隔字符串和(可选)选项将字符串拆分为最大数量的子字符串。

Split(String, StringSplitOptions)

根据提供的字符串分隔符将字符串拆分为多个子字符串。

Split(String[], Int32, StringSplitOptions)

基于指定的分隔字符串和(可选)选项将字符串拆分为最大数量的子字符串。

Split(String[], StringSplitOptions)

基于指定的分隔字符串和(可选)选项将字符串拆分为子字符串。

StartsWith(Char)

确定此字符串实例是否以指定字符开始。

StartsWith(String)

确定此字符串实例的开头是否与指定的字符串匹配。

StartsWith(String, Boolean, CultureInfo)

确定在使用指定的区域性进行比较时此字符串实例的开头是否与指定的字符串匹配。

StartsWith(String, StringComparison)

确定在使用指定的比较选项进行比较时此字符串实例的开头是否与指定的字符串匹配。

Substring(Int32)

从此实例检索子字符串。 子字符串在指定的字符位置开始并一直到该字符串的末尾。

Substring(Int32, Int32)

从此实例检索子字符串。 子字符串从指定的字符位置开始且具有指定的长度。

ToCharArray()

将此实例中的字符复制到 Unicode 字符数组。

ToCharArray(Int32, Int32)

将此实例中的指定子字符串内的字符复制到 Unicode 字符数组。

ToLower()

返回此字符串转换为小写形式的副本。

ToLower(CultureInfo)

根据指定区域性的大小写规则返回此字符串转换为小写形式的副本。

ToLowerInvariant()

返回此 String 对象的转换为小写形式的副本,返回时使用固定区域性的大小写规则。

ToString()

返回 String 的此实例;不执行实际转换。

ToString(IFormatProvider)

返回 String 的此实例;不执行实际转换。

ToUpper()

返回此字符串转换为大写形式的副本。

ToUpper(CultureInfo)

根据指定区域性的大小写规则返回此字符串转换为大写形式的副本。

ToUpperInvariant()

返回此 String 对象的转换为大写形式的副本,返回时使用固定区域性的大小写规则。

Trim()

从当前字符串删除所有前导空白字符和尾随空白字符。

Trim(Char)

从当前字符串删除字符的所有前导实例和尾随实例。

Trim(Char[])

从当前字符串删除数组中指定的一组字符的所有前导匹配项和尾随匹配项。

TrimEnd()

从当前字符串删除所有尾随空白字符。

TrimEnd(Char)

从当前字符串删除字符的所有尾随匹配项。

TrimEnd(Char[])

从当前字符串删除数组中指定的一组字符的所有尾随匹配项。

TrimStart()

从当前字符串删除所有前导空白字符。

TrimStart(Char)

删除当前字符串中的指定字符的所有前导匹配项。

TrimStart(Char[])

从当前字符串删除数组中指定的一组字符的所有前导匹配项。

TryCopyTo(Span<Char>)

将此字符串的内容复制到目标范围。

运算符

Equality(String, String)

确定两个指定的字符串是否具有相同的值。

Implicit(String to ReadOnlySpan<Char>)

定义给定字符串到只读字符范围的隐式转换。

Inequality(String, String)

确定两个指定的字符串是否具有不同的值。

显式接口实现

IComparable.CompareTo(Object)

将此实例与指定的 Object 进行比较,并指示此实例在排序顺序中是位于指定的 Object 之前、之后还是与其出现在同一位置。

IConvertible.GetTypeCode()

返回 String 类的 TypeCode

IConvertible.ToBoolean(IFormatProvider)

有关此成员的说明,请参见 ToBoolean(IFormatProvider)

IConvertible.ToByte(IFormatProvider)

有关此成员的说明,请参见 ToByte(IFormatProvider)

IConvertible.ToChar(IFormatProvider)

有关此成员的说明,请参见 ToChar(IFormatProvider)

IConvertible.ToDateTime(IFormatProvider)

有关此成员的说明,请参见 ToDateTime(IFormatProvider)

IConvertible.ToDecimal(IFormatProvider)

有关此成员的说明,请参见 ToDecimal(IFormatProvider)

IConvertible.ToDouble(IFormatProvider)

有关此成员的说明,请参见 ToDouble(IFormatProvider)

IConvertible.ToInt16(IFormatProvider)

有关此成员的说明,请参见 ToInt16(IFormatProvider)

IConvertible.ToInt32(IFormatProvider)

有关此成员的说明,请参见 ToInt32(IFormatProvider)

IConvertible.ToInt64(IFormatProvider)

有关此成员的说明,请参见 ToInt64(IFormatProvider)

IConvertible.ToSByte(IFormatProvider)

有关此成员的说明,请参见 ToSByte(IFormatProvider)

IConvertible.ToSingle(IFormatProvider)

有关此成员的说明,请参见 ToSingle(IFormatProvider)

IConvertible.ToString(IFormatProvider)

有关此成员的说明,请参见 ToString(IFormatProvider)

IConvertible.ToType(Type, IFormatProvider)

有关此成员的说明,请参见 ToType(Type, IFormatProvider)

IConvertible.ToUInt16(IFormatProvider)

有关此成员的说明,请参见 ToUInt16(IFormatProvider)

IConvertible.ToUInt32(IFormatProvider)

有关此成员的说明,请参见 ToUInt32(IFormatProvider)

IConvertible.ToUInt64(IFormatProvider)

有关此成员的说明,请参见 ToUInt64(IFormatProvider)

IEnumerable.GetEnumerator()

返回循环访问当前 String 对象的枚举数。

IEnumerable<Char>.GetEnumerator()

返回循环访问当前 String 对象的枚举数。

扩展方法

ToImmutableArray<TSource>(IEnumerable<TSource>)

从指定的集合创建一个不可变数组。

ToImmutableDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

通过向源键应用转换函数,从现有元素集合构造一个不可变字典。

ToImmutableDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

基于对序列进行某种形式的转换来构造一个不可变字典。

ToImmutableDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>)

枚举并转换序列,然后生成其内容的不可变字典。

ToImmutableDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IEqualityComparer<TKey>)

枚举并转换序列,然后使用指定的键比较器生成其内容的不可变字典。

ToImmutableDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IEqualityComparer<TKey>, IEqualityComparer<TValue>)

枚举并转换序列,然后使用指定的键和值比较器生成其内容的不可变字典。

ToImmutableHashSet<TSource>(IEnumerable<TSource>)

枚举序列,并生成其内容的不可变哈希集。

ToImmutableHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

枚举序列,生成其内容的不可变哈希集,并为集类型使用指定的相等性比较器。

ToImmutableList<TSource>(IEnumerable<TSource>)

枚举序列,并生成其内容的不可变列表。

ToImmutableSortedDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>)

枚举并转换序列,然后生成其内容的不可变排序字典。

ToImmutableSortedDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IComparer<TKey>)

枚举并转换序列,然后使用指定的键比较器生成其内容的不可变排序字典。

ToImmutableSortedDictionary<TSource,TKey,TValue>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TValue>, IComparer<TKey>, IEqualityComparer<TValue>)

枚举并转换序列,然后使用指定的键和值比较器生成其内容的不可变排序字典。

ToImmutableSortedSet<TSource>(IEnumerable<TSource>)

枚举序列,并生成其内容的不可变排序集。

ToImmutableSortedSet<TSource>(IEnumerable<TSource>, IComparer<TSource>)

枚举序列,生成其内容的不可变排序集,并使用指定的比较器。

CopyToDataTable<T>(IEnumerable<T>)

在给定其泛型参数 TDataTable 的输入 DataRow 对象的情况下,返回包含 IEnumerable<T> 对象副本的 DataRow

CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption)

在给定其泛型参数 TDataRow 的输入 DataTable 对象的情况下,将 IEnumerable<T> 对象复制到指定的 DataRow

CopyToDataTable<T>(IEnumerable<T>, DataTable, LoadOption, FillErrorEventHandler)

在给定其泛型参数 TDataRow 的输入 DataTable 对象的情况下,将 IEnumerable<T> 对象复制到指定的 DataRow

Aggregate<TSource>(IEnumerable<TSource>, Func<TSource,TSource,TSource>)

对序列应用累加器函数。

Aggregate<TSource,TAccumulate>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>)

对序列应用累加器函数。 将指定的种子值用作累加器初始值。

Aggregate<TSource,TAccumulate,TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>, Func<TAccumulate,TResult>)

对序列应用累加器函数。 将指定的种子值用作累加器的初始值,并使用指定的函数选择结果值。

All<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

确定序列中的所有元素是否都满足条件。

Any<TSource>(IEnumerable<TSource>)

确定序列是否包含任何元素。

Any<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

确定序列中是否存在任意一个元素满足条件。

Append<TSource>(IEnumerable<TSource>, TSource)

将一个值追加到序列末尾。

AsEnumerable<TSource>(IEnumerable<TSource>)

返回类型化为 IEnumerable<T> 的输入。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

计算 Decimal 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

计算 Double 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

计算 Int32 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

计算 Int64 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

计算可以为 null 的 Decimal 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

计算可以为 null 的 Double 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

计算可以为 null 的 Int32 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

计算可以为 null 的 Int64 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

计算可以为 null 的 Single 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Average<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

计算 Single 值序列的平均值,这些值可通过对输入序列的每个元素调用转换函数获得。

Cast<TResult>(IEnumerable)

IEnumerable 的元素强制转换为指定的类型。

Chunk<TSource>(IEnumerable<TSource>, Int32)

将序列的元素拆分为最大 size大小的区块。

Concat<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

连接两个序列。

Contains<TSource>(IEnumerable<TSource>, TSource)

通过使用默认的相等比较器确定序列是否包含指定的元素。

Contains<TSource>(IEnumerable<TSource>, TSource, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 确定序列是否包含指定的元素。

Count<TSource>(IEnumerable<TSource>)

返回序列中的元素数量。

Count<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回表示在指定的序列中满足条件的元素数量的数字。

DefaultIfEmpty<TSource>(IEnumerable<TSource>)

返回指定序列中的元素;如果序列为空,则返回单一实例集合中的类型参数的默认值。

DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource)

返回指定序列中的元素;如果序列为空,则返回单一实例集合中的指定值。

Distinct<TSource>(IEnumerable<TSource>)

通过使用默认的相等比较器对值进行比较,返回序列中的非重复元素。

Distinct<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 对值进行比较,返回序列中的非重复元素。

DistinctBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数返回序列中的非重复元素。

DistinctBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数并使用指定的比较器比较键,从序列中返回不同的元素。

ElementAt<TSource>(IEnumerable<TSource>, Index)

返回序列中指定索引处的元素。

ElementAt<TSource>(IEnumerable<TSource>, Int32)

返回序列中指定索引处的元素。

ElementAtOrDefault<TSource>(IEnumerable<TSource>, Index)

返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。

ElementAtOrDefault<TSource>(IEnumerable<TSource>, Int32)

返回序列中指定索引处的元素;如果索引超出范围,则返回默认值。

Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用默认的相等比较器对值进行比较,生成两个序列的差集。

Except<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 对值进行比较,生成两个序列的差集。

ExceptBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>)

根据指定的键选择器函数生成两个序列的集差异。

ExceptBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数生成两个序列的集差异。

First<TSource>(IEnumerable<TSource>)

返回序列中的第一个元素。

First<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的第一个元素。

FirstOrDefault<TSource>(IEnumerable<TSource>)

返回序列中的第一个元素;如果序列中不包含任何元素,则返回默认值。

FirstOrDefault<TSource>(IEnumerable<TSource>, TSource)

返回序列的第一个元素;如果序列不包含任何元素,则返回指定的默认值。

FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足条件的第一个元素;如果未找到这样的元素,则返回默认值。

FirstOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

返回满足条件的序列的第一个元素;如果未找到此类元素,则返回指定的默认值。

GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数对序列中的元素进行分组。

GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数对序列中的元素进行分组,并使用指定的比较器对键进行比较。

GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>)

根据指定的键选择器函数对序列中的元素进行分组,并且通过使用指定的函数对每个组中的元素进行投影。

GroupBy<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据键选择器函数对序列中的元素进行分组。 通过使用比较器对键进行比较,并且通过使用指定的函数对每个组的元素进行投影。

GroupBy<TSource,TKey,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TKey,IEnumerable<TSource>,TResult>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。

GroupBy<TSource,TKey,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TKey,IEnumerable<TSource>,TResult>, IEqualityComparer<TKey>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的比较器对键进行比较。

GroupBy<TSource,TKey,TElement,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, Func<TKey,IEnumerable<TElement>,TResult>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的函数对每个组的元素进行投影。

GroupBy<TSource,TKey,TElement,TResult>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, Func<TKey,IEnumerable<TElement>,TResult>, IEqualityComparer<TKey>)

根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值。 通过使用指定的比较器对键值进行比较,并且通过使用指定的函数对每个组的元素进行投影。

GroupJoin<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,IEnumerable<TInner>,TResult>)

基于键值等同性对两个序列的元素进行关联,并对结果进行分组。 使用默认的相等比较器对键进行比较。

GroupJoin<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,IEnumerable<TInner>,TResult>, IEqualityComparer<TKey>)

基于键值等同性对两个序列的元素进行关联,并对结果进行分组。 使用指定的 IEqualityComparer<T> 对键进行比较。

Intersect<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用默认的相等比较器对值进行比较,生成两个序列的交集。

Intersect<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 对值进行比较,生成两个序列的交集。

IntersectBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>)

根据指定的键选择器函数生成两个序列的集交集。

IntersectBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TKey>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数生成两个序列的集交集。

Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>)

基于匹配键对两个序列的元素进行关联。 使用默认的相等比较器对键进行比较。

Join<TOuter,TInner,TKey,TResult>(IEnumerable<TOuter>, IEnumerable<TInner>, Func<TOuter,TKey>, Func<TInner,TKey>, Func<TOuter,TInner,TResult>, IEqualityComparer<TKey>)

基于匹配键对两个序列的元素进行关联。 使用指定的 IEqualityComparer<T> 对键进行比较。

Last<TSource>(IEnumerable<TSource>)

返回序列的最后一个元素。

Last<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的最后一个元素。

LastOrDefault<TSource>(IEnumerable<TSource>)

返回序列中的最后一个元素;如果序列中不包含任何元素,则返回默认值。

LastOrDefault<TSource>(IEnumerable<TSource>, TSource)

返回序列的最后一个元素;如果序列不包含任何元素,则返回指定的默认值。

LastOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足条件的最后一个元素;如果未找到这样的元素,则返回默认值。

LastOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

返回满足条件的序列的最后一个元素;如果未找到此类元素,则返回指定的默认值。

LongCount<TSource>(IEnumerable<TSource>)

返回表示序列中元素总数的 Int64

LongCount<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回表示序列中满足条件的元素的数量的 Int64

Max<TSource>(IEnumerable<TSource>)

返回泛型序列中的最大值。

Max<TSource>(IEnumerable<TSource>, IComparer<TSource>)

返回泛型序列中的最大值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

对序列中的每个元素调用转换函数,并返回最大的 Decimal 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

对序列中的每个元素调用转换函数,并返回最大的 Double 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

对序列中的每个元素调用转换函数,并返回最大的 Int32 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

对序列中的每个元素调用转换函数,并返回最大的 Int64 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Decimal 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Double 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Int32 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Int64 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最大的 Single 值。

Max<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

对序列中的每个元素调用转换函数,并返回最大的 Single 值。

Max<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)

对序列中的每个元素调用转换函数,并返回最大结果值。

MaxBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数返回泛型序列中的最大值。

MaxBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

根据指定的键选择器函数和键比较器返回泛型序列中的最大值。

Min<TSource>(IEnumerable<TSource>)

返回泛型序列中的最小值。

Min<TSource>(IEnumerable<TSource>, IComparer<TSource>)

返回泛型序列中的最小值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

对序列中的每个元素调用转换函数,并返回最小的 Decimal 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

对序列中的每个元素调用转换函数,并返回最小的 Double 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

对序列中的每个元素调用转换函数,并返回最小的 Int32 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

对序列中的每个元素调用转换函数,并返回最小的 Int64 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Decimal 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Double 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Int32 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Int64 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

对序列中的每个元素调用转换函数,并返回可以为 null 的最小的 Single 值。

Min<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

对序列中的每个元素调用转换函数,并返回最小的 Single 值。

Min<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)

对序列中的每个元素调用转换函数,并返回最小结果值。

MinBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数返回泛型序列中的最小值。

MinBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

根据指定的键选择器函数和键比较器返回泛型序列中的最小值。

OfType<TResult>(IEnumerable)

根据指定类型筛选 IEnumerable 的元素。

OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据键按升序对序列的元素进行排序。

OrderBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

使用指定的比较器按升序对序列的元素进行排序。

OrderByDescending<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据键按降序对序列的元素进行排序。

OrderByDescending<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IComparer<TKey>)

使用指定的比较器按降序对序列的元素排序。

Prepend<TSource>(IEnumerable<TSource>, TSource)

向序列的开头添加值。

Reverse<TSource>(IEnumerable<TSource>)

反转序列中元素的顺序。

Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>)

将序列中的每个元素投影到新表单。

Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,TResult>)

通过合并元素的索引,将序列的每个元素投影到新窗体中。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。 每个源元素的索引用于该元素的投影表。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。 每个源元素的索引用于该元素的中间投影表。

SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用相应类型的默认相等比较器对序列的元素进行比较,以确定两个序列是否相等。

SequenceEqual<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 来比较两个序列的元素,以确定这两个序列是否相等。

Single<TSource>(IEnumerable<TSource>)

返回序列的唯一元素;如果该序列并非恰好包含一个元素,则会引发异常。

Single<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的唯一元素;如果有多个这样的元素存在,则会引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>)

返回序列中的唯一元素;如果该序列为空,则返回默认值;如果该序列包含多个元素,此方法将引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>, TSource)

返回序列的唯一元素;如果序列为空,则返回指定的默认值;如果序列中有多个元素,此方法将引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

返回序列中满足指定条件的唯一元素;如果这类元素不存在,则返回默认值;如果有多个元素满足该条件,此方法将引发异常。

SingleOrDefault<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>, TSource)

返回满足指定条件的序列的唯一元素;如果没有此类元素,则返回指定的默认值;如果多个元素满足条件,此方法将引发异常。

Skip<TSource>(IEnumerable<TSource>, Int32)

跳过序列中指定数量的元素,然后返回剩余的元素。

SkipLast<TSource>(IEnumerable<TSource>, Int32)

返回一个新的可枚举集合,它包含 source 中的元素,但省略了源集合中的 count 个元素。

SkipWhile<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

如果指定的条件为 true,则跳过序列中的元素,然后返回剩余的元素。

SkipWhile<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)

如果指定的条件为 true,则跳过序列中的元素,然后返回剩余的元素。 将在谓词函数的逻辑中使用元素的索引。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Decimal>)

计算 Decimal 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Double>)

计算 Double 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Int32>)

计算 Int32 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Int64>)

计算 Int64 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Decimal>>)

计算可以为 null 的 Decimal 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Double>>)

计算可以为 null 的 Double 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int32>>)

计算可以为 null 的 Int32 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Int64>>)

计算可以为 null 的 Int64 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Nullable<Single>>)

计算可以为 null 的 Single 值序列的总和,这些值可通过对输入序列的每个元素调用转换函数获得。

Sum<TSource>(IEnumerable<TSource>, Func<TSource,Single>)

计算 Single 值序列的总和,这些值可通过对输入序列中的每个元素调用转换函数获得。

Take<TSource>(IEnumerable<TSource>, Int32)

从序列的开头返回指定数量的相邻元素。

Take<TSource>(IEnumerable<TSource>, Range)

返回序列中连续元素的指定范围。

TakeLast<TSource>(IEnumerable<TSource>, Int32)

返回一个新的可枚举集合,它包含 count 中的最后 source 个元素。

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

只要指定的条件为 true,就会返回序列的元素。

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)

只要指定的条件为 true,就会返回序列的元素。 将在谓词函数的逻辑中使用元素的索引。

ToArray<TSource>(IEnumerable<TSource>)

IEnumerable<T> 中创建数组。

ToDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToDictionary<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数和键比较器,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToDictionary<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>)

根据指定的键选择器和元素选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToDictionary<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据指定的键选择器函数、比较器和元素选择器函数,从 IEnumerable<T> 创建一个 Dictionary<TKey,TValue>

ToHashSet<TSource>(IEnumerable<TSource>)

IEnumerable<T> 创建一个 HashSet<T>

ToHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)

使用 comparer 通过 IEnumerable<T> 创建 HashSet<T>,以用于比较键。

ToList<TSource>(IEnumerable<TSource>)

IEnumerable<T> 创建一个 List<T>

ToLookup<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

ToLookup<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数和键比较器,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

ToLookup<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>)

根据指定的键选择器和元素选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

ToLookup<TSource,TKey,TElement>(IEnumerable<TSource>, Func<TSource,TKey>, Func<TSource,TElement>, IEqualityComparer<TKey>)

根据指定的键选择器函数、比较器和元素选择器函数,从 IEnumerable<T> 创建一个 Lookup<TKey,TElement>

TryGetNonEnumeratedCount<TSource>(IEnumerable<TSource>, Int32)

尝试在不强制枚举的情况下确定序列中的元素数。

Union<TSource>(IEnumerable<TSource>, IEnumerable<TSource>)

通过使用默认的相等比较器,生成两个序列的并集。

Union<TSource>(IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)

通过使用指定的 IEqualityComparer<T> 生成两个序列的并集。

UnionBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TSource>, Func<TSource,TKey>)

根据指定的键选择器函数生成两个序列的集联合。

UnionBy<TSource,TKey>(IEnumerable<TSource>, IEnumerable<TSource>, Func<TSource,TKey>, IEqualityComparer<TKey>)

根据指定的键选择器函数生成两个序列的集联合。

Where<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)

基于谓词筛选值序列。

Where<TSource>(IEnumerable<TSource>, Func<TSource,Int32,Boolean>)

基于谓词筛选值序列。 将在谓词函数的逻辑中使用每个元素的索引。

Zip<TFirst,TSecond>(IEnumerable<TFirst>, IEnumerable<TSecond>)

使用两个指定序列中的元素生成元组序列。

Zip<TFirst,TSecond,TThird>(IEnumerable<TFirst>, IEnumerable<TSecond>, IEnumerable<TThird>)

生成包含三个指定序列中的元素的元组序列。

Zip<TFirst,TSecond,TResult>(IEnumerable<TFirst>, IEnumerable<TSecond>, Func<TFirst,TSecond,TResult>)

将指定函数应用于两个序列的对应元素,以生成结果序列。

AsParallel(IEnumerable)

启用查询的并行化。

AsParallel<TSource>(IEnumerable<TSource>)

启用查询的并行化。

AsQueryable(IEnumerable)

IEnumerable 转换为 IQueryable

AsQueryable<TElement>(IEnumerable<TElement>)

将泛型 IEnumerable<T> 转换为泛型 IQueryable<T>

AsMemory(String)

在目标字符串的一部分上创建新的 ReadOnlyMemory<Char>

AsMemory(String, Index)

从指定索引处开始,在目标字符串的一部分上创建新的 ReadOnlyMemory<Char>

AsMemory(String, Int32)

从指定字符串位置开始,在目标字符串的一部分上创建新的 ReadOnlyMemory<Char>

AsMemory(String, Int32, Int32)

从带有长度的指定位置开始,在目标字符串的一部分上创建新的 ReadOnlyMemory<Char>

AsMemory(String, Range)

在目标字符串的指定范围内创建新的 ReadOnlyMemory<Char>

AsSpan(String)

在字符串上创建新的只读跨度。

AsSpan(String, Int32)

从指定位置到字符串结尾,在目标字符串的一部分上创建新的只读跨度。

AsSpan(String, Int32, Int32)

从指定字符数量的指定位置在目标字符串的一部分上创建新的只读跨度。

IsNormalized(String)

指示指定字符串是否符合 Unicode 范式 C。

IsNormalized(String, NormalizationForm)

指示某一字符串是否符合指定 Unicode 范式。

Normalize(String)

将字符串规范化为 Unicode 范式 C。

Normalize(String, NormalizationForm)

将字符串规范化为指定的 Unicode 范式。

Ancestors<T>(IEnumerable<T>)

返回元素集合,其中包含源集合中每个节点的上级。

Ancestors<T>(IEnumerable<T>, XName)

返回经过筛选的元素集合,其中包含源集合中每个节点的上级。 集合中仅包括具有匹配 XName 的元素。

DescendantNodes<T>(IEnumerable<T>)

返回源集合中每个文档和元素的子代节点的集合。

Descendants<T>(IEnumerable<T>)

返回元素集合,其中包含源集合中每个元素和文档的子代元素。

Descendants<T>(IEnumerable<T>, XName)

返回经过筛选的元素集合,其中包含源集合中每个元素和文档的子代元素。 集合中仅包括具有匹配 XName 的元素。

Elements<T>(IEnumerable<T>)

返回源集合中每个元素和文档的子元素的集合。

Elements<T>(IEnumerable<T>, XName)

返回源集合中经过筛选的每个元素和文档的子元素集合。 集合中仅包括具有匹配 XName 的元素。

InDocumentOrder<T>(IEnumerable<T>)

返回节点集合(其中包含源集合中的所有节点),并按文档顺序排列。

Nodes<T>(IEnumerable<T>)

返回源集合中每个文档和元素的子节点集合。

Remove<T>(IEnumerable<T>)

将源集合中的每个节点从其父节点中移除。

适用于

线程安全性

此类型是线程安全的。

另请参阅