Ø  简介

在开发中最常见的数据类型就是 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);    //str2:def, str3:abc

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

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

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

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

讨论: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.Empty、null 或仅由空白字符组成。示例:

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.ArgumentOutOfRangeException:startIndex 不能大于字符串长度。

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("a,bc", 1);  //true

C# 数据类型之 String(字符串)的更多相关文章

  1. 数据类型总结——String(字符串类型)

    相关文章 简书原文:https://www.jianshu.com/p/546a755c3eb6 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...

  2. String字符串加号的作用与基本数据类型加号的作用的区别

    1 public static void main(String args[] ){ 2 String Str="hellow"; 3 int num=110; 4 char c= ...

  3. python数据类型之String(字符串)

    String(字符串) 1.概述 ​ 字符串是以单引号或双引号括起来的任意文本,比如"abc",'xy'等等,请注意''或者""本身只是一种表示方式,并不是字符 ...

  4. redis数据类型之—String

    (1)String 简单介绍 string是redis中最基本的数据类型,一个字符串类型的值存储的最大容量是1GB. (2)String 常用命令

  5. Python基础4:数据类型:数字 字符串 日期

    [ Python 数据类型 ] 我们知道,几乎任何编程语言都具有数据类型:常见的数据类型有:字符串.整型.浮点型以及布尔类型等. Python也不例外,也有自己的数据类型,主要有以下几种: 1.数字: ...

  6. 从零开始学习前端JAVASCRIPT — 3、JavaScript基础string字符串介绍

    1:字符串 JS中的任何数据类型都可以当作对象来看.所以string既是基本数据类型,又是对象. 2:声明字符串 基本数据类型:var sStr = '字符串'; 对象的方法:var oStr = n ...

  7. Java性能优化之String字符串优化

    字符串是软件开发中最重要的对象之一.通常,字符串对象在内存中是占据了最大的空间块,因此如何高效地处理字符串,必将是提高整体性能的关键所在. 1.字符串对象及其特点 Java中八大基本数据类型没有Str ...

  8. 基本数据类型转String,String转基本数据类型

    基本数据类型 --> 字符串 1.基本数据类型+"" String s = 5 + ""; 2.使用包装类的静态方法toString(参数),参数是要转化 ...

  9. Java常用API——String字符串运算

    一.字符串运算 String类 1.概述 String是特殊的引用数据类型,它是final类. 2.构造方法 String str = "abc"; 相当于:  char date ...

随机推荐

  1. [SPOJ375]QTREE - Query on a tree【树链剖分】

    题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...

  2. suoi62 网友跳 (暴搜+dp)

    传送门 sbw太神啦orz 首先N<=20可以直接暴搜 然后玄学剪枝可以过18个点 那么N<=40的时候,就把它拆成两半分别暴搜,再用dp拼起来 对于前半段,设f[i][j]是开始高度为i ...

  3. hdu 2328 Corporate Identity(kmp)

    Problem Description Beside other services, ACM helps companies to clearly state their “corporate ide ...

  4. 牛客小白月赛12 F 华华开始学信息学 (分块+树状数组)

    链接:https://ac.nowcoder.com/acm/contest/392/F来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 32768K,其他语言65536K ...

  5. 关于windows下NODE_ENV=test无效的情况解决办法

    redux的单元测试命令为 NODE_ENV=test mocha --recursive --compilers js:babel-core/register --require ./test/se ...

  6. springboot 通过 hibernate 连接sqlserver 空间数据 位置数据

    示例代码:https://github.com/bigben0123/spring-boot-spatial-example 1,配置application.properties #sqlserver ...

  7. A1136. Delayed Palindrome

    Consider a positive integer N written in standard notation with k+1 digits a​i​​ as a​k​​⋯a​1​​a​0​​ ...

  8. A1006. Sign In and Sign Out

    At the beginning of every day, the first person who signs in the computer room will unlock the door, ...

  9. Miniconda 虚拟环境安装及应用

    首先要下载Miniconda安装包 下载地址  链接:https://pan.baidu.com/s/1rj-9exKBSHnCCxqq7JQSxA      提取码:ab53 下一步 打开下载好的M ...

  10. linux系统调用之文件系统操作

    access 确定文件的可存取性 chdir 改变当前工作目录 fchdir 参见chdir chmod 改变文件方式 fchmod 参见chmod chown 改变文件的属主或用户组 fchown ...