字符、字符串和文本的处理之String类型
.Net Framework中处理字符和字符串的主要有以下这么几个类:
(1)、System.Char类 一基础字符串处理类
(2)、System.String类 一处理不可变的字符串(一经创建,字符串便不能以任何方式修改)
(3)、System.Text.StringBuilder类 一更高效地构建字符串
(4)、System.Secureity.SecureString类 一对字符串进行保护操作,它可以保护密码和信用卡资料等敏感字符串.
一、String类型
1、简介
在任何应用程序里面,String类型都是用的最多的类型之一.一个String代表一个不可变的(immutable)的顺序字符串,String类型直接派生自Object,所以它是引用类型.所以String对象(它的字符串数组)总是存在于堆上,永远不会跑到线程栈.
C#将String视为基元类型,C#编译器允许在源代码中直接使用字面值字符串.编译器将这些字符串存放到模块的元数据中,并在运行时加载和引用它们.
C#不允许使用new操作符从字面值字符串构造String对象,代码如下:
相反,必须使用以下简化语法:
编译代码并检查IL(使用ILDasm.exe),会看到以下内容:
用于构造对象新实例,但上述代码中并没有出现newobj指令,有一个特殊的ldstr(即 load string)指令,它使用从元数据获得的字面值(literal)字符串构造String对象.这证明CLR实际是用一种特殊方式构造字面值String对象
如果使用不安全的(unsafe)代码,可以从一个Char*或Sbyte*参数构造一个String.这时要使用C#的new操作符,并调用由String类型提供的、能接受Char*或Sbyte*参数的某个构造器.这些构造器将创建String对象,根据由Char实例或有符号(signed)字节构成的一个数组来初始化字符串。其他构造器则不允许接受任何指针参数,用任何托管编程语言写的安全(可验证)代码都能调用它们.
2、关于特殊字符的处理:
C#提供了一些特殊的语法来帮助开发人员在源代码中输入字面值(literal)字符串,对于换行符、回车符和退格符这样的特殊字符,C#采用的是C/C++开发人员熟悉的转移机制,代码如下:
- //包含回车符和换行符的字符串
- string s="Hi\r\nthere.";
3、关于字符串连接的问题
- string s="Hi"+" "+"there .";
在上述代码中,由于所有字符串都是字面值,所以C#编译器能在编译时连接它们,最终将一个字符串即(即"Hi there.")放到模块的元数据中.对非字面值字符串使用+操作符,连接则在运行时进行.运行时连接不要用+操作符,因为这样会在堆上创建多个字符串对象,而堆是需要垃圾回收的,对性能有影响.相反,应该使用StringBuilder类型.
4、字符串@转义符
C#提供了一种特殊的字符串声明方式.采取这种方式,印号之间的所有字符都会被视为字符串的一部分.这种特殊声明称为"逐字字符串",通常用于指定文件或目录的路径,或者与正则表达式配合使用。以下代码展示了如何使用和不适用逐字字符串字符(@)来申明同一个字符串,代码如下:
- //指定应用程序路径,使用\解析'\'
- string file="C:\\Windows\\System32\\Notpad.exe";
- //使用逐字字符串制定应用程序路径
- string file=@"C:\Windows\System32\Notepad.exe";
两种写法生成完全一样的字符串,但后者的可读性更好.
5、字符串是不可变的
string对象最重要的一点就是不可变性.也就是所,字符串一经创建遍不能修改其中的任何字符.是字符串不可变有几方面的好处.
字符串不可变有几个方面的好处:
(1)、它允许在一个字符串上执行各种操作,而不实际地更改字符串,如下代码:
- //创建一个字符串
- string str = "zhengchao";
- //然后将字符串转大写,ToUpperInvariant会创建一个临时字符串,垃圾回收器会在下次回收时回收
- var result = str.ToUpperInvariant();
- //输出:false,说明ToUpperInvariant返回了一个新的字符串
- Console.WriteLine("str:'{0}' is Equals result? The answer is {1}",str, ReferenceEquals(str, result));
- //字符串截取,ToUpperInvariant会创建一个临时字符串,垃圾回收器会在下次回收时回收
- var result1 = result.Substring(,);
- //输出:false,说明Substring返回了一个新的字符串
- Console.WriteLine("str is Equals result? The answer is {0}", ReferenceEquals(result, result1));
- //EndsWith对目标字符进行检查不会创建临时字符串
- var result2 = result.EndsWith("ENG");
代码不会长时间引用由ToUpperInvariant和Substring创建的两个临时字符串,垃圾回收器会在下次回收时回收它们的内存.如果执行大量字符串操作,会在堆上创建大量String对象,造成更频繁的垃圾回收,从而影响应用程序性能.so,要高效执行大量字符串操作,建议使用StringBuilder类.
字符串的不可变意味着在操纵或访问字符串时不会发生线程同步问题.此外,CLR可通过一个String对象共享多个完全一直的String内容.
这样能减少系统中的字符串数量一从而节省内存一这就是所谓的"字符串留用".
(2)、实例唯一性
在内存中复制同一个字符串的实例纯属浪费,因为字符串是"不可变"的.在内存中只保留字符串的一个实例将显著提升内存的利用率。需要引用字符串的所有变量只需指向单独的一个字符串对象.
代码如下:
- string str1 = "xiaochao";
- string str2 = "xiaochao";
- Console.WriteLine(ReferenceEquals(str1, str2));//输出:True,说明str1和str2实例指向的是同一个对象
出于对性能的考虑,String类型与CLR紧密集成.具体地说,CLR知道String类型中定义的字段如何布局,会直接访问这些字段.但是为了获得这种性能和直接访问的好处,String只能是密封类.换言之,不能把它作为自己类型的基类.
如果允许String作为基类来定义自己的类型,就能添加自己的字段,而这会破坏CLR对于String类型的各种预设.此外还可能破坏CLR团队应为String对象"不可变"而做出的各种预设.
6、CLR关于语言文化的类型一CultureInfo类和字符串与线程的关联
7、C# 字符串操作基本过程(Equals、Compare、EndsWith等处理方法)
9、C# 高效率创建字符串类(StringBuilder).
11、C# 自定义类型通过实现IFormattable接口,来输出指定的格式和语言文化的字符串(例:DateTime)
12、C# String.Format的格式限定符与Format方法将多个对象格式化一个字符串原理
字符、字符串和文本的处理之String类型的更多相关文章
- [Clr via C#读书笔记]Cp14字符字符串和文本处理
Cp14字符字符串和文本处理 字符 System.Char结构,2个字节的Unicode,提供了大量的静态方法:可以直接强制转换成数值: 字符串 使用最频繁的类型:不可变:引用类型,在堆上分配,但是使 ...
- 字符、字符串和文本的处理之Char类型
.Net Framework中处理字符和字符串的主要有以下这么几个类: (1).System.Char类 一基础字符串处理类 (2).System.String类 一处理不可变的字符串(一经创建,字符 ...
- <NET CLR via c# 第4版>笔记 第14章 字符,字符串和文本处理
14.1 字符 三种数值类型与 Char 实例的相互转换: static void Main() { Char c; Int32 n; //方法一: 通过C#转型(强制类型转换)实现数字与字符的相互转 ...
- clr from c# 字符 ,字符串 和 文本处理
1,字符----------在.net中,字符总是16位的Unicode代码值.每个字符都是一个System.Char结构(值类型)的一个实列. using System; public class ...
- string类型的解释与方法
基本概念 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一.那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unico ...
- JAVA 没有重载运算符,那么 String 类型的加法是怎么实现的,以及String类型不可变的原因和好处
1, JAVA 不具备 C++ 和 C# 一样的重载运算符 来实现类与类之间相互计算 的功能 这其实一定程度上让编程失去了代码的灵活性, 但是个人认为,这在一定程度上减少了代码异常的概率 ...
- 【原创】Java和C#下String类型中的==和equals的原理与区别
一.Java下 1.几个例子 public static void main(String[] arge) { String str1 = new String("1234"); ...
- [CLR via C#]14. 字符、字符串和文本处理
一.字符 在.NET Framewole中,字符总是表示成16位Unicode代码值,这简化了国际化应用程序的开发. 每个字符都表示成System.Char结构(一个值类型) 的一个实例.System ...
- 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制
过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...
随机推荐
- Android 全局搜索条写成自定义控件-曹永思
图文: 1.Android 自定义控件的布局文件 2.编写Android 自定义控件的要处理的逻辑代码(曹永思) 3.在调用自定义控件的 Activity的布局文件中调用Android 称之为控件,控 ...
- 自己写一个chrome扩展程序 - 右键菜单扩展
最近在学习Spring,心想dotnet如何实现类似形式呢.于是想认真学习Casetle组件,发现没有书籍!而spring的书多得很.于是只好找网上教程了.发现系统的文章不多.Terrylee好多文章 ...
- 20171126--idleHadnler的理解使用
相关参考文献: http://www.jianshu.com/p/94d6131a53b2 http://bbs.51cto.com/thread-1094228-1.html https://zhu ...
- (转).net面试题(老赵)
转自:http://www.cnblogs.com/chenxiaoran/archive/2012/05/27/2519988.html 1.什么是CLR 公共语言运行时(Comman langua ...
- webservice之helloword(web)rs
spring整合webservice 1.pom.xml文件 <dependencies> <!-- cxf 进行rs开发 必须导入 --> <dependency> ...
- iOS 应用如何完全支持 IPv6-ONLY 网络?
iOS 应用如何完全支持 IPv6-ONLY 网络?¶ 警告 您当前查看的页面是未经授权的转载! 如果当前版本排版错误,请前往查看最新版本:http://www.cnblogs.com/qin-nz/ ...
- 个人作业四--Alpha阶段个人总结
一.个人总结 在alpha 结束之后, 每位同学写一篇个人博客, 总结自己的alpha 过程: 请用自我评价表:http://www.cnblogs.com/xinz/p/3852177.html 有 ...
- ubuntu下Node.js环境搭建
Node.js是一个能够在服务器端运行JavaScript的开放源代码.跨平台JavaScript运行环境.Node.js由Node.js基金会持有和维护,并与Linux基金会有合作关系.Node.j ...
- 中科大debian 9 + docker源设置
wget https://mirrors.ustc.edu.cn/repogen/conf/debian-http-4-stretch -O sources.list sudo apt-get ins ...
- Linux下安装MySQL以及一些小坑
第一次写博客,各位凑合着看吧(假装有人看). 我这里使用的是centos7. 1.首先打开终端,查看有没有安装过MySQL: [root@localhost lyp]# rpm -qa | grep ...