字符串处理
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)字符串处理的更多相关文章

  1. javaEE基础08

    javaEE基础08 一.继承 特点:继承父类的属性和方法,单继承(多继承) 特性:方法的复写(重写) 比如:人可以养狗 人------>狗:整体和部分(拥有)关系 关键字:extends 结构 ...

  2. hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)

    基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...

  3. redis基础的字符串类型

    redis —— 第二篇 基础的字符串类型 我们都知道redis是采用C语言开发,那么在C语言中表示string都是采用char[]数组的,然后你可能会想,那还不简单,当我执行如下命令,肯定是直 接塞 ...

  4. GoLang基础数据类型--->字符串处理大全

    GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入:   高级运维工程师之路               59843264 ...

  5. Python基础数据类型-字符串(string)

    Python基础数据类型-字符串(string) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客使用的是Python3.6版本,以及以后分享的每一篇都是Python3.x版 ...

  6. Python web前端 08 字符串 数组 json

    Python web前端 08 字符串 数组 json 一.string #string 字符串 #索引 下标 偏移量 ---从0开始 str[index]; #通过索引取字符串 可读不可写 str. ...

  7. C++基础之字符串string

    C++基础之字符串string 标准库类型string表示可变长的字符序列,使用string类型必须首先包含string头文件.作为标准裤的一部分,string定义在命名空间std中. 定义和初始化s ...

  8. Golang的基础数据类型-字符串型

    Golang的基础数据类型-字符串型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符型概述 上一篇博客学习了使用单引号括起来的单个字符就是字符类型,在Golang中有两种表 ...

  9. NOI 1.7编程基础之字符串(35题)

    01:统计数字字符个数 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一行字符,统计出其中数字字符的个数. 输入 一行字符串,总长度不超过255. 输出 ...

  10. c#编程基础之字符串基础

    1.C#中单个的字符串用单引号包含就是char类型,('a'),单引号中放且只能放一个字符 2.单个字符也可以表示为字符串,还可以有长度为0的字符串. 3.使用s.Length属性来获得字符串中的字符 ...

随机推荐

  1. springmvc 使用Jackson的配置

    <!--start:使用Jackson 1.x的配置,需要导入的jar包:jackson-core-lpgl-xxx.jar.jackson-mapper-lgpl-xxx.jar --> ...

  2. jeecms 单页静态化方法

    在论坛上去搜,都说可以需要在模型中配置增加字段,看了云里雾里,调试源代码发现原因,方法如下: 步骤一:改模型 模型管理->"单页“栏目模型->添加: channelStatic( ...

  3. pytest框架 里 fixture 参数化的方法

  4. HDU 2516 取石子游戏(斐波那契)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. pythonNet day03

    TCP应用之 httpserver 1.接收http请求 2.查看http请求 3.返回一个网页给客户端 # 做的是一个本地服务端,接收来自浏览器客户端的请求 from socket import * ...

  6. JavaScript之深拷贝&浅拷贝

    深拷贝&浅拷贝,说起来都明白,但是说不出所以然.今天就系统的整理下思绪,一点点的将其分析出所以然 废话不多说 浅拷贝 简单的说就是一个值引用,学生时代接触过编程的人都应该了解过指针,浅拷贝可以 ...

  7. 20165233 Java第七、十章学习总结

    20165233 2017-2018-2 <Java程序设计>第五周学习总结 教材学习内容总结 ch07 内部类:Java支持在一个类中声明另一个类,这样的类称为内部类,而包含内部类的类称 ...

  8. django-控制mysql事物

    from django.db import transaction 两种方式控制事务:为了保持数据一致性 一个Book表,一个Author表.添加一本书,也要保证添加作者.By事物控制 book = ...

  9. oracle忘记sys及system密码

    一.忘记除SYS.SYSTEM用户之外的用户的登录密码. 用SYS (或SYSTEM)用户登录. CONN SYS/PASS_WORD AS SYSDBA; 使用如下语句修改用户的密码. ALTER ...

  10. layui 弹框

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&q ...