本来写了蛮多的,结果因为重启了一下机器导致写的东西都没了。

然后再回想之前写了什么,反而更像是把知识提炼了一番。

关于字符

字符什么的只要记住.net里面都用的Unicode编码就好。字符和数字之间转换用强制转换是最简单且高效的,

字符串是引用类型,存在与堆上,然而同一般的对象用newobj这个IL指令创建不同,字符串由ldstr指令创建。(load string)

关于字符串

字符串是不可变的,所有的String的方法都是创建一个新的字符串。

用+号去拼接字符串,会在堆上创建多个string对象,而堆上的对象考虑到垃圾回收就会影响性能,所以建议用StringBuilder去拼接。

字符串比较

虽然String提供了一堆比较方法,并且《CLR via C#》这本书的作者也推荐用这些比较,因为==和!=这种比较方式调用者并没有显式指出用什么规则来比较,而如果显示地指出以什么规则来比较,代码容易阅读和维护。

 var str1 = "字符串1";
var str2 = "字符串2";
bool result1= str1.Equals(str2, StringComparison.OrdinalIgnoreCase);//使用序号排列(就是说对本地语言文化不敏感),并忽略大小写来比较。
bool result2 = str1 == str2;//常用的比较

然而,于我而言,确实是==更加明了,这个就看个人了。这些用方法比较的时候确实在有些多语言文化的场景比较好用,然而对于一般场景,我个人认为==更好一点,起码我自己看起来更好阅读和理解。

以StringComparison.Ordinal规则比较的话,CLR会快速先比较字符数量,数量相同才继续比较单独字符。而如果执行语言文化敏感的话,即使数量不同也有可能相等,所以一开始就会比较单个字符,这样就很耗性能。

System.StringComparer类也能执行字符串比较,它适用于大量不同字符串反复执行同一种比较。

字符串留用

CLR可通过一个String对象共享多个完全一致的String内容,这样就减少了字符串数量,节省内存,这就是字符串留用。

在.NET 4.5中自然会在程序集加载时对代码中的字面量字符串进行字符串留用,然而之前的版本就需要手动了。

String.Intern方法就是字符串留用的方法,将字符串加入一个哈希表中,如果哈希表中有就不加入,没有就加入。

这样当然可以减少内存,因为以后只引用一个字符串对象。但是要明白留存字符串这个操作也是需要消耗性能的。所以具体情况具体分析,还是需要慎重使用字符串留存。

字符串池

对于所有的字面量字符串中,相同内容的字符串,实际上都是引用的字符串池中的一个字符串。这是在C#编译器编译的时候就已经弄好的。

高效率构造字符串——StringBuilder

StringBuilder从字面意义上就很好理解了,字符串拼接什么的就用它好了。可以认为里面就是一个字符数组。

然而要理解StringBuilder的以下概念

  • 最大容量(MaxCapacity)

    • 指定了字符串中的最大字符数。默认值是Int32.MaxValue(约20亿)。
    • 一般不用理会,除非是要限制一个字符串的最大字符数。
  • 容量(Capacity)
    • 前面说到,可以将StringBuilder里面认为是一个字符数组,那么容量就指定了当前字符数组的长度。
    • 为什么说是当前呢?因为如果字符串拼接后超过了这个容量值,那么容量就会自动*2,且用新容量来分配新数组,并将原始数组中的字符串复制到新数组中。随后原始数据被垃圾回收。
    • 所以看到这里你就应该很明白一点,用StringBuilder最好在开始的时候自己预估一个容量,最起码不要让他频繁扩容,要不然真是坑,还不如用String。
  • 字符数组
    • 也就是StringBuilder里面由Char结构构成的数组。
    • 它的长度用Length获得

一般用用Append和AppendFormat进行追加字符串,当然也有其它的操作,只要明白里面操作的是一个数组就好。

虽然本书还介绍了一些字符串格式化和解析字符串的方式,然而

字符串编码——字符和字节的相互转换

对于使用汉字的我们使用字符串的话用Unicode没什么影响,因为汉字就占两个字节,然而对于英文字符实际上仅仅用一个字节就够了,但是在Unicode中还是会占两个字节,其中一个字节用于表示这个英文字符,另一个字节干脆就是\0。

所以一些英文翻译啊什么的,或者一大段英文文章的传送,那么将这些Unicode字符串编码成压缩的字节数组传送起来更有效率。

通常也就是用System.IO.BinaryWriter或者System.IO.StreamWriter时,需要进行编码,相应的读取时也需要解码。

一般不指定一种编码方案,那么就默认为UTF-8。(可以简单理解为中文两个字节,英文一个字节)

还有一种常用编码方案是UTF-16,也就是中英文都是两个字节,也被称为Unicode编码。(对于汉字而言,其实用UTF-16编码,比UTF-8更快)

其它的编码方式就不说了,对于我们而言基本上都是坑。

当我们进行编码时尽量用Encoding.Unicode获取编码方案构造对象,而不是用System.Text.UnicodeEncoding这种。

因为前者如果之前有请求会直接返回上次请求的对象给你,不会为每个请求构造新的对象。

而后者每次都会在托管堆中创建新的对象,所以会对性能有所影响。然而在System.Text中的这些派生自Encoding的编码类有特殊的构造器可以在对无效序列解码时抛出异常,所以如果要保证安全性,防范无效输入那么用后面这种比较好。

获取了这些编码方案构造对象后就可以利用GetBytes和GetString来将字符串转换为字节数组和将字节数组转换为字符串。

字节流的编码

就是通过System.Net.Sockets.NetworkStream对象读取一个UTF-16编码字符串,因为这种字节流通常以数据块形式传输,而如果一次从流中读取5个字节,而不是2的倍数的字节数,那么就可能会造成数据损坏。

所以可以用Encoding.Unicode.GetDecoder()获取一个新的构造对象,这个对象含有GetChars和GetCharCount两个方法。调用GetChars时它会尽可能多的解码,如果解码数组的字节不足以完成一个字符时,那么剩余的字符会保存到这个Decoder内部,下次调用它时,此Decoder会利用之前剩余的字节,再加上传给它的字节数组来进行解码。从流中读取Decoder对象的作用很大。

相反的编码一样。

以下为简单的Decoder解码示例

string strTroy = "奇葩";
Byte[] bytesTroy = Encoding.Unicode.GetBytes(strTroy);//形成长度为4的字节数组
Byte[] b1 = { bytesTroy[], bytesTroy[], bytesTroy[] };//一个奇,半个葩
Byte[] b2 = { bytesTroy[] };//半个葩
//以上操作算是模拟了按数据块获取,接下来
var decoder = Encoding.Unicode.GetDecoder();
char[] result=new char[];//解码后的字符数组
var charindex = decoder.GetCharCount(b1, , b1.Length);//若解码b1能形成的字符个数
decoder.GetChars(b1,, b1.Length, result, , false);//第一个0为从b1第0个位置开始解码,第二个0是从result的第0个位置开始写入
decoder.GetChars(b2,, b2.Length, result, charindex, false);
Console.WriteLine(string.Join("",result));//奇葩

安全字符串

System.Security.SecureString类,就是一个更安全的字符串类。

构造这个类的对象后,会在内部分配一个非托管内存块,以避开垃圾回收器。

和String对象不同,SecureString对象在回收后加密字符串的内容将不再存在于内存中。

当然这样的字符串如果不是信用卡啊密码什么的就不需要,毕竟会有性能影响。

【C#进阶系列】14 字符、字符串和文本编码的更多相关文章

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

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

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

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

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

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

  4. .Net进阶系列(14)-异步多线程(async和await)(被替换)

    1.  方法名前只有async,但是方法中Task实例前没有await关键字,该方法和普通方法没有什么区别,但是会报一个警告. #region 情况一 /// <summary> /// ...

  5. C#进阶系列 ---- 《CLR via C#》

      [C#进阶系列]30 学习总结 [C#进阶系列]29 混合线程同步构造 [C#进阶系列]28 基元线程同步构造 [C#进阶系列]27 I/O限制的异步操作 [C#进阶系列]26 计算限制的异步操作 ...

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

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

  7. 重温CLR(十) 字符、字符串和文本处理

    本章将介绍.net中处理字符和字符串的机制 字符 在.NET Framewole中,字符总是表示成16位Unicode代码值,这简化了国际化应用程序的开发. 每个字符都表示成System.Char结构 ...

  8. 13、如何拆分含有多种分隔符的字符串 14、如何判断字符串a是否以字符串b开头或结尾 15、如何调整字符串中文本的格式 16、如何将多个小字符串拼接成一个大的字符串

    13.如何拆分含有多种分隔符的字符串 import re s = "23:41:2314\1234#sdf\23;" print(re.split(r'[#:\;]+',s))   ...

  9. C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)

    前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. 本文原创地址:http://www.cnblog ...

随机推荐

  1. Java中测试异常的多种方式

    使用JUnit来测试Java代码中的异常有很多种方式,你知道几种? 给定这样一个class. Person.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  2. php json与xml序列化/反序列化

    在web开发中对象的序列化与反序列化经常使用,比较主流的有json格式与xml格式的序列化与反序列化,今天想写个jsop的小demo,结果发现不会使用php序列化,查了一下资料,做个笔记 简单数组js ...

  3. Bootstrap~大叔封装的弹层

    回到目录 对于Bootstrap的弹层,插件有很多,今天主要用的是它自带的功能,通过bootstrap提供的模式窗口来实现的,而大叔主要对使用方法进行了封装,开发人员可以自己动态传入弹层的HTML内容 ...

  4. Java线程:线程的交互

      一.线程交互的基础知识   SCJP所要求的线程交互知识点需要从java.lang.Object的类的三个方法来学习:    void notify()           唤醒在此对象监视器上等 ...

  5. MyBatis学习总结(六)——调用存储过程

    一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 1 create table p_user( 2 id int primary key auto_ ...

  6. Atitit jsr规范有多少个  407个。Jsr规范大全

    Atitit jsr规范有多少个  407个.Jsr规范大全 1.1. JCP维护职能是发展和更新.1 1.2. Java技术规范.参考实现(RI).技术兼容包(TCK)1 1.3. JCP维护的规范 ...

  7. Atitit  DbServiceV4qb9 数据库查询类库v4 新特性

    Atitit  DbServiceV4qb9 数据库查询类库v4 新特性     V4新特性 安全特性,屏蔽了executeUpdate,使用v2版 Sql异常转换,特别转换了DuplicateEnt ...

  8. 深度解析SDN——利益、战略、技术、实践(实战派专家力作,业内众多专家推荐)

    深度解析SDN——利益.战略.技术.实践(实战派专家力作,业内众多专家推荐) 张卫峰 编   ISBN 978-7-121-21821-7 2013年11月出版 定价:59.00元 232页 16开 ...

  9. salesforce 零基础学习(三十一)关于LookUp字段点击Save时的Validation

    今天在群里大概遇到了这样一个问题,明明这个User存在,但是save的时候提示信息说Value不存在,大概的意思如下图所示,目前认为这种问题常见的可能情况有两种. 一.此字段设置Validation ...

  10. Microsoft Visual Studio正忙解决办法

    问题描述 前段时间用vs2015进行开发.出现如下问题,关闭vs进程重启vs还是无法解决. 如何解决 进入本地项目.vs文件夹 这个文件夹下有个.suo文件,删除该文件,用任务管理器杀掉vs的进程,重 ...