• C#中的char、string和StringBuilder的使用


    char 字符

    char代表一个Unicode字符,它是System.Char的别名

    char someChar = 'a';//定义了一个字符
    char newLine= '
    ';//这是一个换行符

     System.Char定义了一组静态方法:

    • ToUpper 将指定的字符转换为等效的大写形式
    • ToLower 将指定的字符转换为等效的小写形式
    • IsWhiteSpace 判断指定的字符是否为空白字符
    • ……

    例子:

    Console.WriteLine(char.ToUpper('c'));//输出的是一个大写的C
    Console.WriteLine(char.ToLower('c'));//输出的是还是它自己
    Console.WriteLine(char.ToUpper('C'));//输出的是还是它自己
    Console.WriteLine(char.ToLower('C'));//输出的是一个小写的c
    Console.WriteLine(char.IsWhiteSpace('c'));//输出为False
    Console.WriteLine(char.IsWhiteSpace('	'));//输出为True
    Console.WriteLine(char.IsWhiteSpace(' '));//输出为True

    可以通过char或者System.Char来调用

    例子:

    Console.WriteLine(char.ToUpper('c'));//输出的是一个大写的C
    Console.WriteLine(System.Char.ToUpper('c'));//输出的是一个大写的C

    现在这边会有一个问题,可能会引起一个bug,就是ToUpper,ToLower会遵循用户的地区设置,例如,char.ToUpper('i') == 'I',这句话在土耳其地区设置里就会返回False。

    解决办法就是使用culture-invariant版本的方法,总会应用英语的Culture

    • ToUpperInvariant
    • ToLowerInvariant

    例子:

    //使用固定区域性的大小写规则,不依赖于区域性的设置,以下这两种方式是等价的
    Console.WriteLine(char.ToUpperInvariant('i'));//输出的是大写的I
    Console.WriteLine(char.ToUpper('i', CultureInfo.InvariantCulture));

     char是16bit的,足够代表基本多语言平面的任何Unicode字符,如果超出这个范围,那么必须使用surrogate pairs。

    string 字符串

    • string是System.String的别名
    • string是不可变的
    • string是字符的序列

    如何构建string

    例子:

    string s1 = "Hello";
    string s2 = "First Line
    Second Line";
    string s3 = @"\serverfilesharehelloworld.cs";
    • 创建重复字符的字符串

    使用string的构造函数创建一个重复指定次数的字符的字符串。

    例子:

    Console.WriteLine(new string('*', 10));//输出的结果就是**********
    • 可以从char数组构建字符串

    例子:

    char[] ca = "Hello".ToCharArray();
    string s = new string(ca);

    ToCharArray的作用正好相反,把字符串转成字符数组。

    • string的构造函数也被重载用来接收各种(不安全的)指针类型,目的是从像char*这样的类型创建字符串。

    Null 和 空string

    • 空string的长度是0,通过literal或string.Empty静态字段来创建

    相等性比较的例子:

    string empty = "";
    Console.WriteLine(empty == ""); // True
    Console.WriteLine(empty == string.Empty); // True
    Console.WriteLine(empty.Length == 0); // True
    • string可以为null,因为是引用类型
    string nullString = null;
    Console.WriteLine(nullString == null); // True
    Console.WriteLine(nullString == ""); // False
    Console.WriteLine(nullString.Length == 0); // NullReferenceException

    静态的string.IsNullOrEmpty通常用来判断字符串是否为空或者null,我习惯性使用IsNullOrWhiteSpace,这个判断字符串是否为空或者null或者空白的字符。

    访问string里的字符

    • 通过索引器
    string str = "abcd";
    char letter = str[1]; // letter = 'b'
    • string实现了IEnumerable<char>接口,所以可以foreach里面的每个元素
    // 分别依次输出字符1 、2 、3
    foreach (var item in "123")
    {
        Console.WriteLine(item);
    }

    在string里进行搜索

    最简单的方法包括:StartsWith,EndsWith和Contains。返回的是true或者false。

    Console.WriteLine("HelloWorld.cs".EndsWith(".cs")); // 返回结果为True
    Console.WriteLine("HelloWorld.cs".Contains("World")); // 返回结果为True
    Console.WriteLine("HelloWorld.cs".EndsWith(".CS")); // 返回结果为False
    Console.WriteLine("HelloWorld.cs".Contains("world")); // 返回结果为False

    StartsWith,EndsWith的重载方法允许你指定一个StringComparison枚举或一个CultureInfo对象,以便控制大小写和区域文化的敏感性,默认使用当前本地化的区域设置(locale),并且区分大小写。

    Console.WriteLine("HelloWorld.cs".StartsWith("hello", StringComparison.InvariantCultureIgnoreCase)); // 返回结果为True

    Contains没有提供类似的重载方法,但是你可以使用IndexOf方法,它会返回给定字符/子字符串在被搜索字符串里的首个位置。

    同时,IndexOf提供了重载方法,它可以接收一个起始位置参数(开始搜索的索引值),以及一个StringComparison枚举

    Console.WriteLine("abcde".IndexOf("cd")); // 结果为2
    Console.WriteLine("abcde abcde".IndexOf("CD", 6, StringComparison.CurrentCultureIgnoreCase)); // 结果为8

    LastIndexOf,它和IndexOf类似,但是它是反向搜索

    IndexOfAny,它会返回一组字符里任意一个元素的第一个匹配的位置。

    Console.WriteLine("abc,de f".IndexOfAny(new char[] { ' ', ',' })); // 结果为3
    Console.WriteLine("sdgp5jesu5fa9afe0".IndexOfAny("0123456789".ToCharArray())); // 结果为4

    LastIndexOfAny,功能类似,方向相反

    操纵或者控制 string

    因为string是不可变的,所以所有操纵string的方法返回的都是一个新的string,原来的string是原封不动的。

    Substring,会抽取字符串的一部分出来。

    string left3 = "12345".Substring(0, 3); // 结果就是123
    string mid3 = "12345".Substring(1, 3); // 结果为234
    //如果忽略长度,那么就从起始位置一直到字符串的最后
    string end3 = "12345".Substring(2); // 结果为345

    Insert、Remove,在指定的位置插入、移除字符串。

    string s1 = "helloworld".Insert(5, ","); // 结果为hello,world
    string s2 = s1.Remove(5, 1); // 结果为helloworld

    PadLeft、PadRight,会使用指定的字符(没有指定就是空格)填充string,以达到指定的长度(如果string原本长度就长于指定的长度,那么它就不变)。

    Console.WriteLine("12345".PadLeft(10, '*')); // 输出结果就是*****12345
    Console.WriteLine("12345".PadLeft(10)); // 输出结果就是     12345

    TrimStart,TrimEnd从开始或结尾移除指定的字符(默认是空白符:空格,tab,换行以及Unicode里相应的变种)。

    Trim,会把开始和结尾的空白字符都移除。

    Console.WriteLine("   abc  
      ".Trim().Length); // 结果为3

    Replace,替换所有指定的字符/字符串,(非重叠的)。

    Console.WriteLine("hello world".Replace(" ", " | ")); // 结果为hello | world
    Console.WriteLine("hello world".Replace(" ", "")); // 结果为helloworld

    ToUpper,ToLower,返回string的大/小写等等效形式。默认情况下也遵循用户当前的语言设定,与上面的char的方法一样,不再赘述。

    拆分、合并字符串

    Split方法可以拆分字符串。

    • 默认使用空格作为分隔符
    • 重载方法可以接收param字符数组,或string作为分隔符
    • 可选接收StringSplitOptions枚举作为参数,有个选项可以移除空的字符串
    string[] words = "my name is bob".Split();
    //打印结果依次输出my name is bob四个单词
    foreach (var item in words)
    {
        Console.WriteLine(item);
    }
    string[] split1 = "123-abc".Split('-');
    //打印结果依次输出123和abc两个字符串
    foreach (var item in split1)
    {
        Console.WriteLine(item);
    }
    string[] split2 = "123-abc-".Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
    //打印结果依次输出123和abc两个字符串,最后一个空项会被移除
    foreach (var item in split2)
    {
        Console.WriteLine(item);
    }

    Join(静态)方法,功能与Split相反,用于合并成一个字符串,它需要一个分隔符和字符串数组。

    string[] words = "my name is bob".Split();
    Console.WriteLine(string.Join(",", words)); // 输出结果为一个字符串my,name,is,bob

    Concat(静态)方法,和Join类似,但是只接收params string数组作为参数,无需分隔符。和+的效果一样,起始编译器就是把它翻译成+。

    string str1 = string.Concat("hello", "world"); // 结果为helloworld
    string str2 = "hello" + "world"; // 结果为helloworld

    String.Format 和 复合格式的string

    Format(静态)方法,提供了一个方便的方式来构建嵌入变量的字符串,嵌入的变量/值可以是任何类型,Format会调用它们的ToString方法。

    含有嵌入变量的string就叫做复合格式string(composite format string)。

    当你调用String.Format的时候,你就得传入一个复合格式string,后边跟着它里面嵌入的这些变量。

    string composite = "ab{0}cd{1}e";
    Console.WriteLine(string.Format(composite, "123", 456)); // 结果为ab123cd456e

    大括号里的每个数字都叫做格式化项(format item),数值对应参数(argument)的位置,并且后边可以跟着:

    • 一个逗号,和一个要应用的最小宽度(通常用来对齐列,负数表示左对齐,正数表示右对齐)
    • 一个冒号,和一个格式化字符串(format string)
    string composite = "Name={0, -20} Credit Limit={1,15:C}";
    Console.WriteLine(string.Format(composite, "Bob", 500));
    Console.WriteLine(string.Format(composite, "Elizatech", 20000));

    结果如下:

     从C#6开始,你可以使用字符串插值的方式(interpolated string literals)。

    int value = 32;
    Console.WriteLine($"abc{value}"); //结果为abc32

    比较 string

    在.NET里,用来比较两个string的概念有两个:

    • 相等性比较,Equality
    • 顺序比较,Order

    相等性比较就是测试两个字符串实例在语义上是否相等。而顺序比较是指在正序倒序排列的时候,谁应该出现在前面。

    相等性比较不是顺序比较的子集。

    对于字符串相等性的比较来说,可以使用:

    • == 运算符
    • string的某个Equals方法(这种方式有很多选项)

    上述两种方式还有一个重要的差别就是,如果string变量转换成了object对象,那么==运算符就不再可靠了。

    对于字符串的顺序比较来说,可以使用:

    • 实例的CompareTo方法
    • 静态的Compare和CompareOrdinal方法。第一个值在第二个值的后边,返回正数,第一个值在第二个值的前边,返回负数,两个值并列,返回0。

    序数 VS 文化 比较(Ordinal VS Culture Comparison)

    有两个基本的算法用来做string比较:

    • Ordinal
    • Culture-sensitive

    Ordinal比较,会把字符解析成数字(根据它们的Unicode数值),例如:A 是 U+0041,a 是 U+0061。

    Culture-sensitive比较,通过引用特定的字母表来解析字符。

    两个常用或者特殊的Culture:

    • 当前的Culture
    • Invariant Culture

    对于相等性比较而言,Ordinal和Culture-specific算法都有用。而对于顺序比较来说,更倾向于culture-specific比较(文化相关的),按字母表对string进行排序,所以肯定需要一个字母表。

    Ordinal依赖于Unicode的Code point数值,英文字母正好是字母表的顺序,不知道是这么设计的还是巧合。

    例子:

    如果考虑大小写,对一下三个字符串排序:

    "Ada", "Tom", "ada"

    Invariant Culture算法的排序结果是: "ada", "Ada", "Tom"

    Invariant Culture算法封装了字母表,并且认为大写字母所对应的小写字母是相邻的(aAbBcC…)。

    Ordinal算法的排序结果是:"Ada", "Tom", "ada"

    Ordinal算法里,大写字母都在前面,小写字母都在后面(A…Z,a…z)。

    尽管Ordinal算法有一定限制,但是==运算符在进行string相等性比较的时候,总会考虑ordinal大小写。实例版的string.Equals方法如果不传参数的话,效果也是一样,这就是string类型的默认的相等性比较行为。

    Ordinal算法被string的==和Equals函数选择,是因为它的高效和确定性。

    下面这两个方法可以设定是否考虑Culture和大小写进行string比较:

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

    静态版本的方法优势在于:如果两个字符串有null的情况,那么仍然可以正常工作。

    StringComparison有哪些值呢:

     下面我们来看几个例子:

    Console.WriteLine("Hello" == "hello" ); // False
    Console.WriteLine(string.Equals("Hello", "hello", StringComparison.OrdinalIgnoreCase)); // True
    
    Console.WriteLine("u" == "ü"); // False
    Console.WriteLine(string.Equals("u", "ü", StringComparison.CurrentCulture)); // ?

    string排序比较,string的示例方法是CompareTo,会执行culture相关的、大小写相关的排序比较。与string的相等性比较不同,CompareTo没有使用Ordinal比较算法,对于排序来说,Culture敏感的算法更有用。

    方法的定义:

    public int CompareTo(String strB);

    CompareTo实例方法实现了泛型IComparable接口,该接口在.NET里面是一个标准的比较协议。

    而对于其它类型的比较,可以使用静态的Compare和CompareOrdinal方法。

    所有的排序比较方法都会返回一个:正数/负数/0

    第一个值在第二个值的后面,返回正数;第一个值在第二个值的前面,返回负数;两个值并列,返回0。

    Console.WriteLine("Base".CompareTo("Auto")); // 返回1
    Console.WriteLine("Base".CompareTo("Base")); // 返回0
    Console.WriteLine("Base".CompareTo("China")); // 返回-1
    Console.WriteLine("base".CompareTo("Base")); // 返回-1
    Console.WriteLine(string.Compare("base", "Base", true)); // 返回0

    CultureInfo 对象

    使用CultureInfo对象,就可以插入任何一个字母表

    CultureInfo这个类是定义在System.Globalization命名空间下的

    CultureInfo german = CultureInfo.GetCultureInfo("de-DE");
    Console.WriteLine(string.Compare("Müller", "Muller", false, german)); // 返回结果是1

    StringBuilder

    StringBuilder类(System.Text命名空间)代表的是可编辑或者叫可改变的字符串

    使用StringBuilder,你可以Append追加、Insert插入、Remove移除和Replace替换子字符串,而不用替换整个StringBuilder。

    StringBuilder的构造函数可可以接收一个初始化的string值,以及内部容量的初始大小(默认是16字符)。如果超过了这个大小,StringBuilder会自动重新改变其内部结构的大小(轻微的性能损耗)以适应最大容量(默认是int.MaxValue)。

    AppendLine,会执行Append动作,区别在于此操作会自定添加一个换行(Windows环境下是" ")。

    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.Append("123");
    stringBuilder.Append("456");
    Console.WriteLine(stringBuilder.ToString()); // 结果为123456
    stringBuilder.AppendLine("789");
    Console.WriteLine(stringBuilder.ToString()); // 结果是123456789后面换行了
    stringBuilder.AppendLine("abc");
    Console.WriteLine(stringBuilder.ToString());

    AppendFormat,接收一个复合格式字符串,和string.Format一样。

    StringBuilder还有一个Length属性,获取长度的属性。

    StringBuilder还有一个索引器,用来读取每个字符的可写的索引器。

    想要清除StringBuilder的内容,可以初始化一个新的StringBuilder,或者把Length属性设为0。但是把StringBuilder的Length属性设为0并没有缩小它的容量,它占用的内存大小是不变的,想要释放内容,必须要new一个,而且要保证原来的实例可以被GC。

  • 相关阅读:
    SharePoint无法搜索解决
    SharePoint自动登录问题
    SharePoint2013 中集成AD RMS 与Office Web App 2013集成
    SharePoint中使用Visio Service展示业务数据
    Office Web App2013 在线查看PDF文件
    在SharePoint中无代码开发InfoPath应用: 获取当前用户信息
    在SharePoint中无代码开发InfoPath应用: 一个测试Web Service的工具
    使用RDCMan管理SharePoint虚拟机的重复要求验证的问题
    SharePoint 2013开发环境准备一些小事项
    SharePoint部署工具SPSD
  • 原文地址:https://www.cnblogs.com/njabsky/p/13336678.html
Copyright © 2020-2023  润新知