.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等处理方法)

8、字符串留用与字符串池

9、C# 高效率创建字符串类(StringBuilder).

10、C# 获取所有对象的字符串表示一ToString方法

11、C# 自定义类型通过实现IFormattable接口,来输出指定的格式和语言文化的字符串(例:DateTime)

12、C# String.Format的格式限定符与Format方法将多个对象格式化一个字符串原理

 

字符、字符串和文本的处理之String类型的更多相关文章

  1. [Clr via C#读书笔记]Cp14字符字符串和文本处理

    Cp14字符字符串和文本处理 字符 System.Char结构,2个字节的Unicode,提供了大量的静态方法:可以直接强制转换成数值: 字符串 使用最频繁的类型:不可变:引用类型,在堆上分配,但是使 ...

  2. 字符、字符串和文本的处理之Char类型

    .Net Framework中处理字符和字符串的主要有以下这么几个类: (1).System.Char类 一基础字符串处理类 (2).System.String类 一处理不可变的字符串(一经创建,字符 ...

  3. <NET CLR via c# 第4版>笔记 第14章 字符,字符串和文本处理

    14.1 字符 三种数值类型与 Char 实例的相互转换: static void Main() { Char c; Int32 n; //方法一: 通过C#转型(强制类型转换)实现数字与字符的相互转 ...

  4. clr from c# 字符 ,字符串 和 文本处理

    1,字符----------在.net中,字符总是16位的Unicode代码值.每个字符都是一个System.Char结构(值类型)的一个实列. using System; public class ...

  5. string类型的解释与方法

    基本概念 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一.那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unico ...

  6. JAVA 没有重载运算符,那么 String 类型的加法是怎么实现的,以及String类型不可变的原因和好处

    1, JAVA 不具备 C++ 和 C# 一样的重载运算符 来实现类与类之间相互计算 的功能    这其实一定程度上让编程失去了代码的灵活性, 但是个人认为,这在一定程度上减少了代码异常的概率     ...

  7. 【原创】Java和C#下String类型中的==和equals的原理与区别

    一.Java下 1.几个例子 public static void main(String[] arge) { String str1 = new String("1234"); ...

  8. [CLR via C#]14. 字符、字符串和文本处理

    一.字符 在.NET Framewole中,字符总是表示成16位Unicode代码值,这简化了国际化应用程序的开发. 每个字符都表示成System.Char结构(一个值类型) 的一个实例.System ...

  9. 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制

    过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...

随机推荐

  1. windows10 搭建Dubbo

    1.官方文档 http://dubbo.apache.org/zh-cn/docs/admin/ops/dubbo-ops.html 2.下载安装包 https://mirrors.cnnic.cn/ ...

  2. 远程算数程序——版本v1.0

    很少有需要背诵的程序,但是从这个程序开始,标记的都是必须背诵的. 远程算数程序概述 远程算数程序比较简单,分为服务器端和客户端,客户端发送欲计算的表达式给服务器端,服务端经过计算又返回结果给客户端.如 ...

  3. 适配android和iOS上position:absolute和input问题

    //适配android上absolute和input的问题var oHeight = $(document).height(); //屏幕当前的高度$(window).resize(function( ...

  4. mysql查询 根据年月日的查询

    select * from call_loan_info where DATE_FORMAT(create_time,'%Y-%m-%d') = '2017-06-16'

  5. _编程语言_C语言_C++_时间

    C++ 标准库没有提供日期类型,使用C预压的日期和事件操作. 使用时引入头文件  <ctime> . 四个和事件相关的函数: clock_t // 系统时间和日期表示为某种整数time_t ...

  6. (动态规划)matrix -- hdu -- 5569

    http://acm.hdu.edu.cn/showproblem.php?pid=5569 matrix Time Limit: 6000/3000 MS (Java/Others)    Memo ...

  7. jQuery 与 或 的坑

    <!DOCTYPE html><html><head><meta charset="UTF-8"><title>< ...

  8. Circles and Pi

    Circles and Pi Introduction id: intro-1 For as long as human beings exist, we have looked to the sky ...

  9. hdu 1.2.8

    #include<cstdio> #include<iostream> using namespace std; int pow(int a,int b) { ; while( ...

  10. 语音识别功能_微信小程序代办清单任务

    最近想给自己的代办清单任务微信小程序想加个语音识别识别功能,废话不多说,直接说重点,语音识别使用的是百度语音识别api,因为微信小程序的录音输入文件目前只能是mp3或aac 但是百度语音识别不支持这两 ...