zoukankan      html  css  js  c++  java
  • C# 数据类型之 String(字符串)

    Ø  简介

    在开发中最常见的数据类型就是 String 类型,即字符串类型。为什么要单独讨论下这个类型,是因为:它是系统内置的基础数据类型;它的使用频率非常高;它是一个特殊的引用类型。其实大家都会使用它,但可能或多或少了解不够全面,本文主要是抱着:学习、巩固、总结的目的去加深对它的了解,主要学习以下几点:

    1.   什么是 string 类型

    2.   创建 string 对象的方式

    3.   string 的常用静态方法

    4.   string 的常用实例方法

    5.   string 的常用扩展方法

    6.   string 的使用技巧

    7.   char 的常用静态方法

     

    1.   什么是 string 类型

    1)   它主要用于存储一组连续字符(char),一个完整的字符串对象可以看作是一个 char 类型的数组,既然是数组我们就可以把它当作集合去使用,例如:

    string str1 = "abc";

    char[] chars = new char[str1.Length];

    //方式1

    for (int i = 0; i < chars.Length; i++)

        chars[i] = str1[i];

    //方式2

    chars = str1.ToArray();

     

    2)   它是一种特殊的引用类型

    1.   MSDN 上,string 就被分为引用类型,https://msdn.microsoft.com/zh-cn/library/t63sy5hs(VS.80).aspx

    另外,从声明上也可以看出,它是一个密封的 class

    public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>

    注:可见,string 实现了 IEnumerable<char> 接口,所以 string 也可以使用很多 IEnumerable<char> 接口的扩展方法。

     

    2.   string 的值具有不变性

    string 最显著的特点就是它具有恒定不变性,我们一旦创建了一个 string 对象,就不能以任何方式改变该对象的值,比如:追加、删减、改变格式等。有时看上去改变了某个字符串,但实际上则是创建了一个新的字符串实例。

     

    3.   为什么又说它是一种特殊的引用类型呢,是因为它是引用类型,有时却表现出值类型的特点,例如:

    1)   示例一

    string str2 = "abc";

    string str3 = str2;

    str2 = "def";

    Console.WriteLine("str2:{0}, str3:{1}", str2, str3);    //str2def, str3abc

    首先,将"abc"存储在内存中,并将引用地址赋给 str2;然后,将 str2 的引用赋给 str3,此时 str2 str3 具有相同的引用;最后,改变了 str2 的值(注意是新值并不是改变),此时 str2 str3 并不是引用同一个内存地址。所以,最终输出并不相同。(个人理解)

    clip_image001

     

    2)   示例二(以上示例解释通了,下面的示例又做如何解释)

    StringTestOne stringTestOne1 = new StringTestOne() { Name = "爱变成" };

    StringTestOne stringTestOne2 = stringTestOne1;

    stringTestOne2.Name = "张无忌";

    Console.WriteLine("One1.Name:{0}, One2.Name:{1}", stringTestOne1.Name, stringTestOne2.Name);    //One1.Name:张无忌, One2.Name:张无忌

    首先,创建了一个包含 Name 属性的对象;然后,将该对象的引用赋值给 stringTestOne2;之后,再改变了 stringTestOne2.Name 的值;结果,输出两个对象的 Name 属性,尽然是一样的值。

    这样是不是有点蒙了,为什么跟上面的示例不太一样呢?我们先看引用情况:

    bool bool1_1 = object.ReferenceEquals(stringTestOne1, stringTestOne2);              //true

    bool bool1_2 = object.ReferenceEquals(stringTestOne1.Name, stringTestOne2.Name);    //true

    没错,它们是相同的对象引用,无论是对象还是属性,都是同一个引用地址。

    至此,再画张图解释一下:

    clip_image003

    讨论:http://social.msdn.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/ce580186-86d9-45f7-b5ff-20302caf1324

     

    2.   创建 string 对象的方式

    1)   直接赋值

    string str5 = "abc";    //在堆中创建对象,并将引用分配给变量 str5

    2)   调用 string 的构造函数(+ 7 重载)

    string str6 = new string(new char[] { 'a', 'b', 'c' });

     

    3.   string 的常用静态方法

    1)   Compare() 方法+ 10 重载,比较两个字符串。示例:

    int int1 = string.Compare("acd", "abc");  //1

    int int2 = string.Compare("123", "135");  //-1

    int int3 = string.Compare("", "");    //0

     

    2)   Concat() 方法+ 10 重载,连接(串联)每个参数示例:

    string str7 = string.Concat("abc", true, 3);    //abcTrue3

     

    3)   Join () 方法+ 4 重载,使用指定的分隔符,连接(串联)每个参数示例:

    string str8 = string.Join(",", new int[] { 1, 2, 3 });  //1,2,3

    string str8_1 = string.Join(",", new int[] { 1 });      //1

    string str8_2 = string.Join(",", new int[] { });        //""

    string str8_3 = string.Join(",", null);                 //System.ArgumentNullException:值不能为 null

     

    4)   Copy() 方法,将指定的字符串的值拷贝到新的字符串。示例:

    string str9 = "abc123";             //abc123

    string str10 = str9;                //abc123

    string str11 = string.Copy(str9);   //abc123

    bool bool1 = str9.Equals(str10);    //true

    bool bool2 = str9.Equals(str11);    //true

    bool bool3 = object.ReferenceEquals(str9, str10);   //true

    bool bool4 = object.ReferenceEquals(str9, str11);   //false

    注:可见,使用 Copy() 方法拷贝值的方式,与原对象的引用不同。

     

    5)   Equals() 方法+ 2 重载,比较两个字符串的值是否相等。示例:

    string str12 = "abc123";

    string str13 = "abc123";

    bool bool5 = string.Equals(str12, str13);           //true

    bool bool6 = object.ReferenceEquals(str12, str13);  //true

    bool bool6_1 = string.Equals("a", "A", StringComparison.CurrentCulture);            //false

    bool bool6_2 = string.Equals("a", "A", StringComparison.CurrentCultureIgnoreCase);  //true

    注:可见,相同值的字符串对象并不会重复创建,这个很关键!

     

    6)   Format() 方法(+ 4 重载),根据指定的格式格式化字符串。示例:

    string str14 = string.Format("格式化{0}", "字符串");      //格式化字符串

    //输出字符串包含“{”时,需要使用"{{"转义

    string str15 = string.Format("{{格式化{0}", "字符串");    //{格式化字符串

    //string str16_1 = string.Format("{0}{1}", "a");    //System.FormatException:索引(从零开始)必须大于或等于零,且小于参数列表的大小。

    string str16_2 = string.Format("{0}{1}", "a", "b", "c");    //ab(注:可见,参数列表可多不可少,多余的则忽略。)

     

    1.   去除小数点后面无效的零

    string str16_3 = string.Format("{0:0.##}", 16.00m);     //16

    string str16_4 = string.Format("{0:0.##}", 16.10m);     //16.1

    string str16_5 = string.Format("{0:0.##}", 16.06m);     //16.06

    string str16_6 = string.Format("{0:0.##}", 16.160m);    //16.16

    string str16_7 = string.Format("{0:0.##}", 16.164m);    //16.16

    string str16_8 = string.Format("{0:0.##}", 16.165m);    //16.17(注:进行了四舍五入)

     

    7)   IsNullOrEmpty() 方法,检查指定的字符串是否为 string.Empty null示例:

    bool bool7 = string.IsNullOrEmpty("");      //true

    bool bool8 = string.IsNullOrEmpty(null);    //true

    bool bool9 = string.IsNullOrEmpty(" ");     //false

     

    8)   IsNullOrEmpty() 方法,检查指定的字符串是否为 string.Emptynull 或仅由空白字符组成。示例:

    bool bool10 = string.IsNullOrWhiteSpace("");    //true

    bool bool11 = string.IsNullOrWhiteSpace(null);  //true

    bool bool12 = string.IsNullOrWhiteSpace(" ");   //true

    bool bool13 = string.IsNullOrWhiteSpace("1");   //false

     

    9)   CompareOrdinal() 方法,通过计算每个字符串中相应 System.Char 对象的数值来比较两个指定的 System.String 对象。示例:

    int int3_1 = string.CompareOrdinal("abc123", "abc123");     //0

    int int3_2 = string.CompareOrdinal("abc123", "def123");     //-3

    int int3_3 = string.CompareOrdinal("dec123", "abc123");     //3

     

    4.   string 的常用实例方法

    1)   CompareTo() 方法(+ 2 重载),比较两个字符串。示例:

    int int4 = "acd".CompareTo("abc");  //1

    int int5 = "123".CompareTo("135");  //-1

    int int6 = "".CompareTo("");    //0

    注:该方法与静态方法 CompareTo() 类似。

     

    2)   Contains() 方法(+ 2 重载),查找此实例中是否包含指定的字符串。示例

    bool bool14 = "abc123".Contains("c1");  //true

    bool bool15 = "abc123".Contains("c2");  //false

     

    3)   StartsWith() 方法(+ 2 重载),查找此实例开头是否为指定的字符串。示例:

    bool bool16 = "abc123".StartsWith("ab");    //true

    bool bool17 = "abc123".StartsWith("bc");    //false

    bool bool18_1 = "abc".StartsWith("abc");    //true

     

    4)   EndsWith() 方法(+ 2 重载),查找此实例末尾是否为指定的字符串。示例:

    bool bool18 = "abc123".EndsWith("23");      //true

    bool bool19 = "abc123".EndsWith("12");      //false

    bool bool20_1 = "abc".EndsWith("abc");      //true

     

    5)   Equals() 方法(+ 2 重载),比较此实例是否与指定的字符串的值相等。示例:

    bool bool20 = "abc123".Equals("abc123");    //true

    bool bool21 = "abc123".Equals(" abc123");   //false

    bool bool21_1 = "a".Equals("A", StringComparison.CurrentCulture);           //false

    bool bool21_2 = "a".Equals("A", StringComparison.CurrentCultureIgnoreCase); //true

    注:该方法与静态方法 Equals() 类似。

     

    6)   GetTypeCode() 方法,获取此实例对应的 System.TypeCode 枚举值。该方法实现于 System.IConvertible 接口,所有的基础数据类型都实现了该接口。示例:

    TypeCode tc1 = "123".GetTypeCode(); //TypeCode.String

     

    7)   IndexOf() 方法(+ 8 重载),获取指定字符或字符串在此实例中【第一次出现的索引,索引从零开始。示例:

    int int7 = "abc123".IndexOf("b");   //1

     

    8)   IndexOfAny() 方法(+ 2 重载),获取指定的字符数组的任意字符在此实例中【第一次出现的索引,索引从零开始。示例:

    int int8 = "abc123".IndexOfAny(new char[] { '2', '3', '1' });    //3

    注:可见,在查找前字符数组进行了升序排序,并没有按照索引顺序匹配。

     

    9)   LastIndexOf() 方法(+ 8 重载),获取指定字符或字符串在此实例中【最后一次出现的索引,索引从零开始。示例:

    int int9 = "abc123123".LastIndexOf("1");    //6

     

    10)  LastIndexOfAny() 方法(+ 2 重载),获取指定的字符数组的任意字符在此实例中【最后一次出现的索引,索引从零开始。示例:

    int int10 = "abc123123".LastIndexOfAny(new char[] { '2', '3', '1' });    //8

    注:可见,在查找前字符数组进行了降序排序,并没有按照索引顺序匹配。

     

    11)  Insert() 方法,返回在此实例的指定索引处插入字符串后的新字符串,索引从零开始。示例:

    string str16 = "abc123".Insert(0, "lcl");   //lclabc123

     

    12)  PadLeft() 方法(+ 1 重载),返回在此实例的【左侧】填充指定的字符来达到指定的长度。示例:

    string str17 = "abc123".PadLeft(6, 'x');    //abc123

    string str18 = "abc123".PadLeft(8, 'x');    //xxabc123

     

    13)  PadRight() 方法(+ 1 重载),返回在此实例的【右侧】填充指定的字符来达到指定的长度。示例:

    string str19 = "abc123".PadRight(6, 'x');   //abc123

    string str20 = "abc123".PadRight(8, 'x');   //abc123xx

     

    14)  Remove() 方法(+ 1 重载),返回在此实例中移除指定起始位置和数量后的字符串,索引从零开始。示例:

    string str21 = "abc123".Remove(3, 1);   //abc23

     

    15)  Replace() 方法(+ 1 重载),返回此实例在指定的旧值被新值替换后的字符串。示例:

    string str22 = "abc123".Replace("abc", "def");   //def123

     

    16)  Split() 方法(+ 5 重载),返回此实例在指定的字符数组分割后的字符串数组。示例:

    char[] separator = { ' ', ',' };

    StringSplitOptions options = StringSplitOptions.RemoveEmptyEntries;

    string[] strs1 = ",a b,c".Split(separator);             //["", "a", "b", "c"]

    string[] strs2 = ",a b,c".Split(separator, options);    //["a", "b", "c"]

    string[] strs3 = ",a b,c".Split(separator, 3);          //["", "a", "b,c"]

    string[] strs4 = ",a b,c".Split(separator, 3, options); //["a", "b", "c"]

    string[] strs5 = "abc".Split(separator, options);       //["abc"]

    string[] strs6 = "".Split(separator, options);          //[]

     

    17)  Substring() 方法(+ 1 重载),在此实例中检索指定起始位置至指定长度的子字符串,索引从零开始。示例:

    string str23 = "abc123".Substring(1);       //bc123

    string str24 = "abc123".Substring(1, 2);    //bc

    string str24_1 = "abc123".Substring(0);     //abc123

    string str24_2 = "abc123".Substring(6);     //""

    string str24_3 = "abc123".Substring(7);     //System.ArgumentOutOfRangeExceptionstartIndex 不能大于字符串长度。

    string str24_4 = "STAT items:1:number 2";

    string str24_5 = str24_4.Substring(11, str24_4.LastIndexOf(':') - 11);  //1 str24_4.Substring(11("1"), 12 - 11);

     

    18)  ToCharArray() 方法(+ 1 重载),将此实例复制到字符数组中,且可指定起始位置及长度,索引从零开始。示例:

    char[] chars1 = "".ToCharArray();           //[]

    char[] chars2 = "abc".ToCharArray();        //['a', 'b,', 'c']

    char[] chars3 = "abc".ToCharArray(1, 1);    //['b']

     

    19)  ToLower() 方法(+ 1 重载),返回此实例的【小写】形式的副本。示例:

    string str25 = "ABc123".ToLower();          //abc123

     

    20)  ToUpper() 方法(+ 1 重载),返回此实例的【大写】形式的副本。示例:

    string str26 = "abC123".ToUpper();          //ABC123

     

    21)  TrimStart() 方法(+ 1 重载),移除此实例中的【前导】空格 或 匹配指定字符数组的字符。示例:

    string str27 = " okakabcok ".TrimStart();               //|okakabcok |

    string str28 = " okakabcok ".TrimStart('k', ' ', 'o');  //|akabcok |

     

    22)  TrimEnd() 方法(+ 1 重载),移除此实例中的【尾部】空格 或 匹配指定字符数组的字符。示例:

    string str29 = " okabcakok ".TrimEnd();                 //| okabcakok|

    string str30 = " okabcakok ".TrimEnd('k', ' ', 'o');    //| okabca|

     

    23)  Trim() 方法(+ 1 重载),移除此实例中的【首尾】空格 或 匹配指定字符数组的字符。示例:

    string str31 = " okabcakok ".Trim();                    //|okabcakok|

    string str32 = " okabcakok ".Trim('k', ' ', 'o');       //|abca|

     

    5.   string 的常用扩展方法

    Ø  string 的扩展主要是借助了 IEnumerable<char> 接口的扩展,使用这些扩展方法之前,首先需要引入 System.Linq 命名空间。

    1)   获取第一个字符

    char char1 = "abc123".FirstOrDefault();     //a

     

    2)   获取指定索引处的字符,索引从零开始

    char char2 = "abc123".ElementAt(1);         //b

     

    3)   反转字符串

    string str36 = new string("abc123".Reverse().ToArray());    //321cba

     

    4)   字符串排序

    string str37 = new string("132cab".OrderBy(o => o).ToArray());              //123abc

    string str38 = new string("132cab".OrderByDescending(o => o).ToArray());    //cba321

     

    5)   去除字符串中的重复字符

    string str39 = new string("abc123abc123".Distinct().ToArray()); //abc123

     

    Ø  总之,IEnumerable<char> 接口的扩展方法,字符串对象都可以运用之,因为 string 就是一个 char 类型的集合,这里就不一一列举了。

     

    6.   string 的使用技巧

    1)   连接字符串

    string str50 = null;

    string str51 = str50 + "abc";                   //abc

    string str52 = string.Format("{0}abc", str50);  //abc

     

    2)   生成字符串

    string str56 = string.Join(",", Enumerable.Range(1, 5));    //1,2,3,4,5

    string str57 = string.Empty.PadLeft(5, 'a');                //aaaaa

     

    3)   获取字符串宽度

    string str61 = "获取字符串宽度";

    using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))

    {

        int fontSize = 9;

        SizeF sizeF = graphics.MeasureString(str61, new Font("宋体", fontSize));

        float width = sizeF.Width;  //90.49804

    }

    说明:这里需要使用 System.Drawing.Graphics 类,需要另外引用 System.Drawing.dll 程序集。

    注:WinForm 中还可以使用 Control 类,获取 Graphics 的实例,例如:

    Graphics graphics = (new System.Windows.Forms.Control()).CreateGraphics();

     

    4)   字符串与字节数组互转

    //字符串 转为 字节数组

    byte[] bytes1 = Encoding.Default.GetBytes("");     //[165, 193]

    byte[] bytes2 = Encoding.Default.GetBytes("");     //[165, 235]

    byte[] bytes3 = Encoding.Default.GetBytes("");     //[206, 210]

    byte[] bytes4 = Encoding.Default.GetBytes("a");     //[97]

    byte[] bytes5 = Encoding.Default.GetBytes("A");     //[65]

    byte[] bytes6 = Encoding.Default.GetBytes("1");     //[49]

    byte[] bytes7 = Encoding.Default.GetBytes("#");     //[35]

    byte[] bytes8 = Encoding.Default.GetBytes("");      //[]

    byte[] bytes9 = Encoding.Default.GetBytes(" ");     //[32]

    byte[] bytes10 = Encoding.Default.GetBytes(".");    //[46]

    byte[] bytes11 = Encoding.Default.GetBytes("");   //[161, 163]

    byte[] bytes12 = Encoding.Default.GetBytes(",");    //[44]

    byte[] bytes13 = Encoding.Default.GetBytes("");   //[163, 172]

    //字节数组 转为 字符串

    string str66 = Encoding.Default.GetString(bytes3);  //

    string str67 = Encoding.Default.GetString(bytes4);  //a

     

    5)   字符串与 Base64编码 互转

    string str71 = "字符串与 Base64编码 互转";

    //字符串 转为 Base64编码

    byte[] byte21 = Encoding.Default.GetBytes(str71);

    string str72 = Convert.ToBase64String(byte21);     //19a3+7Su0+sgQmFzZTY0seDC6yC7pdeq

    //Base64编码 转为 字符串

    byte[] byte22 = Convert.FromBase64String(str72);

    string str73 = Encoding.Default.GetString(byte22);  //字符串与 Base64编码 互转

     

    7.   char 的常用静态方法

    1)   IsWhiteSpace() 方法(+ 2 重载),查找指定位置的字符是否为空白字符。例:

    bool bool1_1 = char.IsWhiteSpace(' ');        //true

    bool bool1_2 = char.IsWhiteSpace('a');        //false

    bool bool1_3 = char.IsWhiteSpace("a bc", 1);  //true

    bool bool1_4 = char.IsWhiteSpace("a bc", 2);  //false

     

    2)   IsPunctuation() 方法(+ 2 重载),查找指定位置的字符是否为标点符号。例:

    bool bool2_1 = char.IsPunctuation('a');         //false

    bool bool2_2 = char.IsPunctuation(',');         //true

    bool bool2_3 = char.IsPunctuation("a,bc", 1);   //true

    bool bool2_4 = char.IsPunctuation("abc", 1);  //true

  • 相关阅读:
    HDOJ/HDU 2560 Buildings(嗯~水题)
    HDOJ/HDU 2555 人人都能参加第30届校田径运动会了(判断加排序~)
    POJ1703Find them, Catch them
    BZOJ2303: [Apio2011]方格染色
    BZOJ2809: [Apio2012]dispatching
    POJ1611The Suspects
    BZOJ2006: [NOI2010]超级钢琴
    BZOJ2288: 【POJ Challenge】生日礼物
    BZOJ1150: [CTSC2007]数据备份Backup
    洛谷P1316 P1824
  • 原文地址:https://www.cnblogs.com/abeam/p/7522467.html
Copyright © 2011-2022 走看看