.NET基础 (08)字符串处理
字符串处理
1 System.String是值类型还是引用类型
2 StringBuilder类型有何作用
3 如何在String和Byte[]对象之间进行转换
4 简述BASE64编码的作用以及C#中对其的支持
5 SecureString的实例如何被分配和释放
6 什么是字符串池机制
字符串处理
1 System.String是值类型还是引用类型
System.String 是引用类型,它的对象在初始化后就不能再做修改,任何试图修改字符串对象的动作都将导致一个新的字符串对象的产生。
示例代码:
static void Main(string[] args)
{
String a = "我是字符串";
String b = a;
Console.WriteLine(Object.ReferenceEquals(a, b)); //尝试使用引用b修改a指向的对象
b = "我是新的字符串"; Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(Object.ReferenceEquals(a, b));
Console.Read();
}
输出结果:
True
我是字符串
我是新的字符串
False
2 StringBuilder类型有何作用
String的性能问题产生于其内容不可修改的特性。当一个字符串对象被修改、插入、连接、截断是,新的字符串对象将被分配,这会影响性能。更加常见的情况是,一个字符串对象的最终生成需要经过一个组装过程,而在这个组装过程中必将产生很多临时字符串对象。这些对象在堆上分配,需要垃圾回收器来回收,这些动作会对程序产生巨大的影响。而事实上,在字符串组装过程中,其临时对象都不是最终需要的,可以说是不必要分配的。
这样就产生了对StringBuilder类型的需求。StringBuilder类型的设计思想源于构造器的设计模式。构造器设计模式致力于解决复杂对象的构造问题,而对于字符串对象,正需要这样的构造器来进行组装。StringBuilder类型在最终产生String对象之前,将不产生任何String对象,这很好的解决了字符串的性能问题。一旦StringBuilder的ToSting方法被调用后,最终的字符串就被产生,而随后的操作将导致一个新的字符串对象的分配。
对于非托管的代码,字符串的操作是直接基于内存的,如果使用字符串类型和非托管资源进行操作,那潜在地违反了字符串对象不可变的原则。所有StringBuilder常常别用来和非托管代码进行交互。
3 如何在String和Byte[]对象之间进行转换
比特
比特(bit)是指一个位。
字节
字节(byte)在C#中由8个比特来构成。它的值可以由一个0~255的整数表示,但是C#中不允许隐式地把一个整数变量赋值给一个字节变量,下面的代码将编译错误:
int i = 10;
byte b = i;
编码
编码可以说是数字信息和现实信息的转换机制。一种编码常常就定义一种字符集合转换的原则,常用的编码方式包括UTF8、GB2312、Unicode 等。
字符串和字节数组的转换依赖于编码方式的使用,不同的编码准则使用不同的算法进行。System.Text.Encoding类型提供了大部分常见的编码算法支持,用以进行字符串和字节数组直接的转换。
示例代码:
class StringByte
{
static void Main(string[] args)
{
String s = "我是字符串,I am string"; //字节数组转换到字符串
Byte[] utf8 = StringToByte(s,
Encoding.UTF8);
Byte[] gb2312 = StringToByte(s,
Encoding.GetEncoding("GB2312"));
Byte[] unicode = StringToByte(s,
Encoding.Unicode);
Console.WriteLine(utf8.Length);
Console.WriteLine(gb2312.Length);
Console.WriteLine(unicode.Length); //转换回字符串
Console.WriteLine(ByteToString(utf8,
Encoding.UTF8));
Console.WriteLine(ByteToString(gb2312,
Encoding.GetEncoding("GB2312")));
Console.WriteLine(ByteToString(unicode,
Encoding.Unicode));
Console.Read();
}
static Byte[] StringToByte(String s, Encoding encoding)
{
return encoding.GetBytes(s);
}
static String ByteToString(Byte[] b, Encoding encoding)
{
return encoding.GetString(b);
}
}
输出:
27
22
34
我是字符串,I am string
我是字符串,I am string
我是字符串,I am string
4 简述BASE64编码的作用以及C#中对其的支持
BASE64编码是一种用于混淆明码的编程方式,其算法是把原来8位字节数组顺序分配到新的6位字节数组中,再在每个字节的高2位填充0来组成新的8位字节数组。在.NET中Covert类型可以用来进行BASE64字符串和8位字节数组之间的转换。
static void Main(string[] args)
{
String abc = "abcde";
//生成UTF8字节数组
Byte[] bytes = Encoding.UTF8.GetBytes(abc);
//转换成Base64字符串
String base64 = BytesToBase64(bytes);
Console.WriteLine(base64);
//转换回UTF8字节数组
bytes = Base64ToBytes(base64);
//转换回字符串
Console.WriteLine(Encoding.UTF8.GetString(bytes));
Console.Read();
}
//把8位字节数组转换成Base64字符串
static String BytesToBase64(Byte[] bytes)
{
try
{
return Convert.ToBase64String(bytes);
}
catch
{
return null;
}
}
//把Base64字符串转换成8位字节数组
static Byte[] Base64ToBytes(String base64)
{
try
{
return Convert.FromBase64String(base64);
}
catch
{
return null;
}
}
输出:
YWJjZGU=
abcde
5 SecureString的实例如何被分配和释放
System.SecureString 提供了加密的字符串类型。其对象会被分配在非托管堆中,并以加密的形式保存。对于SecureString的操作都是逐字符的,SecureString会负责在操作时进行加密和解密。SecureString实现了标准的Dispose/Finalize方法,对象被释放是先被全部布置为0,以保证机密信息不会在内存中驻留过长时间。
static void Main(string[] args)
{
//使用using保证Dispose方法被调用
using (SecureString ss = new SecureString())
{ //只能逐字符地访问SecureString对象
ss.AppendChar('a');
ss.AppendChar('c');
ss.AppendChar('d');
ss.InsertAt(, 'c');
PrintSecurityString(ss);
Console.Read();
}
} public unsafe static void PrintSecurityString(SecureString ss)
{
char* buffer = null;
try
{ //只能逐字符地访问SecureString对象
buffer = (char*)Marshal.SecureStringToCoTaskMemUnicode(ss);
for (int i = ; *(buffer + i) != '\0'; i++)
Console.Write(*(buffer + i));
Console.Write("\r\n");
}
finally
{ //释放内存
if (buffer != null)
Marshal.ZeroFreeCoTaskMemUnicode((System.IntPtr)buffer);
}
}
为了显示SecureString的内容,程序要访问非托管资源内存块,PrintSecurityString使用了unsafe关键字,所以编译时需要添加/unsafe 开发。
如果出现编译错误:不安全代码只会在使用 /unsafe 编译的情况下出现。只需要把程序属性中的“生成”标签下的“允许不安全代码”勾上就好了。

运行输出:
accd
6 什么是字符串池机制
字符串池机制致力于改善程序的性能。CLR会保留程序中出现过的字符串对象的集合,并且在需要新的字符串时,先检查已有的集合,在检查成功时返回已有对象的引用。如果不存在,则新分配一个字符串对象,同时把其添加到内部容器中。但是当程序用new关键字明显地申明新分配一个字符串对象时,该机制不会起作用。字符串池机制可以通过程序集元数据特性进行控制,C#默认是打开字符串池机制的。
static void Main(string[] args)
{
//两个字符串对象,理论上引用应该不相等
//但由于字符串池的机制,两者实际指向了同一对象
String a = "abcde";
String b = "abcde";
Console.WriteLine(Object.ReferenceEquals(a, b)); //在本书前面章节的例子已中有介绍,编译器会优化这样的代码
//所以这行代码等同于String c="abcde";
//由于字符串池,c和a还是指向同一对象
String c = "a" + "b" + "c" + "d" + "e";
Console.WriteLine(Object.ReferenceEquals(a, c)); //显式使用new来分配内存
//这时候字符串池机制不能起作用,d和a指向不同对象
Char[] chars ={ 'a', 'b', 'c', 'd', 'e' };
String d = new String(chars);
Console.WriteLine(Object.ReferenceEquals(a, d)); Console.Read();
}
输出:
True
True
False
转载请注明出处:
作者:JesseLZJ
出处:http://jesselzj.cnblogs.com
.NET基础 (08)字符串处理的更多相关文章
- javaEE基础08
javaEE基础08 一.继承 特点:继承父类的属性和方法,单继承(多继承) 特性:方法的复写(重写) 比如:人可以养狗 人------>狗:整体和部分(拥有)关系 关键字:extends 结构 ...
- hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)
基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...
- redis基础的字符串类型
redis —— 第二篇 基础的字符串类型 我们都知道redis是采用C语言开发,那么在C语言中表示string都是采用char[]数组的,然后你可能会想,那还不简单,当我执行如下命令,肯定是直 接塞 ...
- GoLang基础数据类型--->字符串处理大全
GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入: 高级运维工程师之路 59843264 ...
- Python基础数据类型-字符串(string)
Python基础数据类型-字符串(string) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客使用的是Python3.6版本,以及以后分享的每一篇都是Python3.x版 ...
- Python web前端 08 字符串 数组 json
Python web前端 08 字符串 数组 json 一.string #string 字符串 #索引 下标 偏移量 ---从0开始 str[index]; #通过索引取字符串 可读不可写 str. ...
- C++基础之字符串string
C++基础之字符串string 标准库类型string表示可变长的字符序列,使用string类型必须首先包含string头文件.作为标准裤的一部分,string定义在命名空间std中. 定义和初始化s ...
- Golang的基础数据类型-字符串型
Golang的基础数据类型-字符串型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符型概述 上一篇博客学习了使用单引号括起来的单个字符就是字符类型,在Golang中有两种表 ...
- NOI 1.7编程基础之字符串(35题)
01:统计数字字符个数 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 输入一行字符,统计出其中数字字符的个数. 输入 一行字符串,总长度不超过255. 输出 ...
- c#编程基础之字符串基础
1.C#中单个的字符串用单引号包含就是char类型,('a'),单引号中放且只能放一个字符 2.单个字符也可以表示为字符串,还可以有长度为0的字符串. 3.使用s.Length属性来获得字符串中的字符 ...
随机推荐
- [原创]JEECMS 自定义标签调用广告版位下的所有广告(利用广告管理管理首页幻灯片)
JEECMS自带的只有[@cms_advertising]标签,并且官方没有给文档,用法: [@cms_advertising id='3'] <img src=&quo ...
- volatile的本质
1. 编译器的优化 在本次线程内, 当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中:以后,再取变量值时,就直接从寄存器中取值:当变量值在本线程里改变时,会同时把变量的新 ...
- Haroopad安装与配置: Linux系统下最好用的Markdown编辑器
1. Haroopad概述 Haroopad is a markdown enabled document processor for creating web-friendly documents. ...
- 【python】FTP客户端
Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件,函数列举如下 ftp登陆连接 from ftplib import FTP #加 ...
- [持续更新]一些zyys的题的集合
Luogu P1119 灾后重建 Sol:对于每个中转点K,需且仅需以此松弛一次 Key words:Floyd,本质活用 考题 路径数 题目描述: Euphemia到一个N*N的药草田里采药,她从左 ...
- 关于RouterOS 国内DDNS服务
虽然RouterOS 加入了cloud功能,但最近在配置RB2011的时候发现不好使,更新域名后无法正确解析到我的IP地址,虽然在cloud的public address中显示了正确的公网ip地址,但 ...
- 配置mysql环境变量
配置mysql环境变量(非必要) 说明:给mysql配置环境变量后我们就可以在cmd里运行mysql(开启.停止等操作) 1. 和其实环境变量的配置方法一样,我们打开环境变量配置窗口(组合键win+P ...
- 小米笔记本pro CPU GPU 做科学计算的算力对比
小米笔记本pro:15.6寸,i7-8850,16G,256G,GPU:MX150 测试对象Caffe,MNIST训练 使用纯CPU训练: 1.耗时:11分58秒 2.功耗:35W 使用GPU训练: ...
- Pyhton项目实践:将带有美国风格日期的文件改名为欧洲风格日期
题目 项目要求:上千个文本文件,文件名包含美国风格的日期( MM-DD-YYYY),需要将它们改名为欧洲风格的日期( DD-MM-YYYY) 先写个创建一百个美国风格日期的文件 #! python # ...
- 用 Vue 改造 Bootstrap,渐进提升项目框架
前言 Vue 横空出世,以迅雷不及掩耳之势横扫前端界,俨然有当年 jQuery 之势.我认为 Vue 成功的关键在于三点: 学习曲线平缓,有点经验的前端基本上一天就能看完文档,然后就可以上手操作. 上 ...