string关键字表示一个字符串(零个或更多 Unicode 字符),它对应.NET的System.String。请注意,我们在前面的章节中所学习的bool、byte、short、int、long、float、double、decimal等基础数据类型都是值类型,因为它们都是以struct关键字声明和定义的,而string则是由class关键字声明和定义的,所以,string并不是一个值类型,而是引用类型。
尽管string是引用类型,它的值会存储在托管堆内存中,但在实际的使用过程中,它看起来像值类型一样。例如可以使用相等运算符(== 和 !=)进行比较,或者两个字符串相加变成一个字符串。
观察下面的例子
static void Main(string[] args)
{
string name = "李";
name = name + "莫愁";
Console.WriteLine($"name = {name}");
Console.ReadKey();
}
输出结果:name = 李莫愁
由此可见,我们先定义一个叫name的字符串变量,并赋值为字符串"李",然后加了一个字符串"莫愁",最后将这个变量的值打印出来,所以是"李莫愁"。看起来我们是修改了name的值。
实际上,字符串的值是不可以修改的!
咦,这句话怎么理解?字符串对象name被创建后,会在内存中开辟一个空间(假定地址a),当执行 name = name + "莫愁" 这句话时,编译器实际上会创建一个新字符串对象来保存新的字符序列,再将新对象赋给 name变量,而name变量的地址一直不变,只是值发生了改变。最后字符串”李“将被无情的遗忘,由.NET垃圾回收器在适当的时候进行内存回收。
我们再看看字符串对比是否相等的例子
static void Main(string[] args)
{
string a = "hello";
string b = "h";
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);
Console.ReadKey();
}
输出结果:
True
False
这里说明字符串的值是可以直接对比的,但是两个字符串变量由于不是引用同一个字符串实例,所以二者是不等的。
关于字符串的几种形式
1、普通字符串:使用双引号引起来。
string name = "李莫愁";
Console.WriteLine($"name = {name}");
2、转义字符串:
string name = "李莫愁\n外号赤练仙子";
Console.WriteLine($"name = {name}");
输出结果
name = 李莫愁
外号赤练仙子
这次在字符串中间增加了\n,表示换行,所以输出结果变成了两行。以\开头的表示转义字符,例如:
转义字符 | 意义 | ASCII码值(十进制) |
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符"\" | 092 |
\' | 代表一个单引号(撇号)字符 | 039 |
\" | 代表一个双引号字符 | 034 |
\? | 代表一个问号 | 063 |
\0 | 空字符(NUL) | 000 |
\ddd | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 十六进制所代表的任意字符 | 十六进制 |
3、带@的原义字符串
string name = @"李莫愁\n外号赤练仙子";
Console.WriteLine($"name = {name}");
输出结果:
name = 李莫愁\n外号赤练仙子
这次\n失去了作用,被当作普通字符输出,这是因为在字符串的前面加了一个@。使整个字符串变成了原义字符串。
4、参数字符串
$"name = {name}"
这时我们在字符串前面增加了一个$美元符号,双引号中间可以使用大括号将某个变量括起来,最后使用这个字符串时,大括号里面的内容会替换成变量的值。
字符串是区分大小写的,观察下面的例子
string a = "\u0068ello ";
string b = "world";
Console.WriteLine(a + b);
Console.WriteLine(a + b == "hello world");
Console.WriteLine(a + b == "Hello world");
输出结果
hello world
True
False
创建字符串的几种方式
static void Main(string[] args)
{
//第一种 字符串连接
string fname, lname;
fname = "赤练仙子";
lname = "李莫愁";
string fullname = fname + lname;
Console.WriteLine("全名: {0}", fullname);
//第二种 构造函数
char[] words = { '赤', '练', '仙', '子', '李', '莫', '愁' };
string word = new string(words);
Console.WriteLine("全称: {0}", word);
//第三种 方法返回字符串
string[] array = { "赤练仙子", "李莫愁" };
string message = string.Join("-", array);
Console.WriteLine("称号: {0}", message);
//第四种 Format格式化
string date = string.Format("日期:{0:D} 时间:{0:t}", DateTime.Now);
Console.WriteLine(date);
Console.ReadKey();
}
输出结果
全名: 赤练仙子李莫愁
全称: 赤练仙子李莫愁
称号: 赤练仙子-李莫愁
日期:2024年1月20日 时间:11:00
——重庆教主 2024年1月20日