值类型: bool、byte、char、enum、sbyte以及数字类型(包括可空类型)
类型分类
引用类型: class、interface、delegate(委托)、object、string
而string与其它引用类型不同,举个例子:
string str1 = "hello";
string s = str1;
str1 = "world";
Console.WriteLine(str1);//word
Console.WriteLine(s);//hello
发现str1重新赋值并不会改变s。
string的恒定性
在为string赋值=时,它是新建了一个字符串,而没有对原string修改。
在为str1重新赋值,只是将变量str1的指针指向“world”的内存地址,对“hello”的内存地址不会有改变。
string驻留机制
字符串的线程同步(同一个字符串对象可以在不同的应用程序域中被访问,所以驻留的字符串是进程级的,垃圾回收不能释放这些字符串对象,只有进程结束这些对象才被释放)。
例子说明字符串的驻留现象:
string str1 = "hello";
string str2 = "hello";
Console.WriteLine(ReferenceEquals(str1,str2));//true
ReferenceEquals比较字符串是否来自同一内存引用,两个字符串来自同一块内存。
驻留机制:CLR(多种语言运行时)对相同的字符串,在栈上只分配一次内存。CLR内部维护着一块特殊的数据结构,我们叫它字符串池,可以把它理解成是一个HashTable,如果找到,则直接把该字符串的地址返回给相应的变量,如果没有才会在内存中新建一个字符串对象。
在连接string上的应用
例子:
string str1 = "hello"+"world";
string str2 = "helloworld";
Console.WriteLine(ReferenceEquals(str1,str2));//true
string s1 = "hello";
string str1 = s1+"world";
string str2 = "helloworld";
Console.WriteLine(ReferenceEquals(str1,str2));//false
发现:1如果使用常量连接,则驻留机制生效
2.使用变量连接,则驻留机制失效
当然,当字符串驻留机制无效时,我们可以使用string.Intern方法将其手动驻留至字符串池中
string s = "hello";
string str1 = s+"world";
string str2 = "helloworld";
Console.WriteLine(ReferenceEquals(string.Intern(str1),str2));//true
关于==,Equals,ReferenceEquals的总结
1.==,如果是值类型,则比较引用和值,因为string是存在栈上的,所以string比较的是引用和值,如果为引用类型,则比较地址。
2.Equals,比较的是堆里面的值是否相等
3.ReferenceEquals,比较的是堆上内存地址是否相等
常见问题
(1)“string = ”与“new string()”的区别
两者效果一样,加载字符串时间不同,且后者没有字符串驻留。
(2)string 与 String的区别
string是类似于int的基元类型;System. String是框架类库(FCL)的基本类型,二者之间有直接的对应关系
(3).StringBuilder
点这里
string常用函数
static void Main(string[] args)
{
string str = "123456456";
//正向查找(IndexOf)
int index = str.IndexOf("234");
Console.WriteLine(index);
//反向查找(LastIndexOf)
index = str.LastIndexOf("456");
Console.WriteLine(index);
//移除(Remove),不会改变原字符
//从指定下标开始到结尾,全移除
string str1 = str.Remove(2);
Console.WriteLine(str1);//12
//第一个参数为开始下标,第二个为字符个数
string str2 = str.Remove(1, 3);
Console.WriteLine(str2);//156456
//替换(Replace),不会改变原字符
string str3 = str.Replace("123", "hello");
Console.WriteLine(str3);//hello456456
//大写转小写(ToLower)
//小写转大写(ToUpper)
//截取(Substring)
string s = "hello world";
string str4 = s.Substring(2);
Console.WriteLine(str4);
string str5 = s.Substring(1, 4);
Console.WriteLine(str5);//ello
//字符串切割
string s1 = "1_1|2_2|3_3|4_4";
string[] strs = s1.Split('|');
for(int i=0;i<strs.Length;i++)
{
Console.WriteLine(strs[i]);
}
Console.ReadKey();
}