String和StringBuilder
在使用String类时常常存在这样一个问题:当每次为同一个字符串重新赋值时,都会在内存中创建一个新的字符串对象,需要为该新对象分配新的空间,这样会加大系统的开销。因为system.String类是一个不可变的数据类型,一旦对一个字符串对象进行初始化后,该字符串对象的值就不能改变了。当对该字符串的值做修改时,实际上是又创建了一个新的字符串对象。现在我们来分析由以下三个语句组成的这段代码的输出结果是什么。
String strText = "Hello";
strText += "World";
Console.WriteLine(strText);
答案很简单 ,不难看出上面这段代码的输出结果是“HelloWorld”。但是,这段代码创建了几个对象呢?让我们用图示的方式进行说明。在执行第一个语句时,首先创建了一个String类对象,值为“Hello”,然后通过赋值运算符将该对象的引用赋给strText。
执行第二个语句时,从表面上看strText更新了值。但实际上内存中又新创建了两个新的对象,其值分别是“World”和“HelloWorld”。此时,内存中存在三个对象,分别是Hello、World和HelloWorld。而strTest所引用的是HelloWorld对象。如果程序中出现这种反复多次修改内容的String对象,系统开销耗费很大,可能会造成应用程序运行性能的降低。如何避免这种情况呢?有没有一个类既能重复修改又不必创建新的对象呢?有,这就是C#中的StringBuilder类。
接下来介绍StringBuilder类对象的定义及处理方法。
为了解决上面的问题,Microsoft提供了System.Text.StringBuilder类,表示可变字符串。虽然StringBuilder类不想String类具有很多字符串处理的方法,但是在替换、添加或删除字符串时,StringBuilder类对象的执行速度要比String类对象快得多。现在我们来看下StringBuilder类对象是如何定义的。
语法:
//声明一个空的StringBuilder对象
StringBuilder 对象名称 = new StringBuilder( );
//声明一个StringBuilder对象,值为“字符串初始值”
StringBuilder 对象名称 = new StringBuilder("字符串初始值");
例如,
System.Text.StringBuilder sbText = new StringBuilder( );
sbText.Append("Hello");
sbText.Append("HelloWorld");
在上面这段代码中,使用StringBuilder类时先要引用System.Text命名空间,然后创建StringBuilder对象sbText。当sbText对象调用Append()方法时,在sbText对象的原字符串后面追加新的字符串,而不是创建一个新对象。StringBuilder类是动态分配空间的,允许扩充它所封装的字符串中的字符数。如果需要,可以使用ToString()方法把sbText对象的值转换为String类型输出。
StringBuilder常用的属性和方法
属性 |
说明 |
Capacity |
获取或设置可包含在当前对象所分配的内存中的最大字符个数 |
Length |
获取或设置当前对象的长度 |
方法 |
说明 |
StringBuilder Append(string value) |
在结尾追加 |
StringBuilder Append(string format,object arg0,object arg1) |
添加特定格式的字符串 |
StringBuilder Insert(int index,string value) |
在指定位置插入指定字符串 |
Remove(int startIndex,int length) |
移除指定字符串 |
- 在程序调试状态弹出“文本可视化工具”对话框的步骤如下。
设置断点→启动调试→将查看值放入监视窗口→单机监视窗口中“值”列右侧的放大镜小图标,即可弹出“文本可视化工具”对话框。
- 编写SQL语句时,在数据库的表名、列名两端添加一对方括号[],可以区别一些特殊的不符合命名规则的字符串,或防止数据库表的列名与系统关键字相冲突。如假设表明为Select,SQL语句为“SELECT * FROM Select;”将会产生语法错误。但是如果改为“SELECT * FROM [Select];”,这就是一个正确的SQL语句,可以正常执行。
注意:
- 如果要将StringBuilder类对象转换为String类对象,唯一的方式是使用ToString()方法。
- StringBuilder类并不总能提高性能,他基本上在处理多个字符串时使用。如果只是连接两个字符串,使用System.String类会比较好。
查询数据
上一章中,我们讲解了如何通过Connection对象将应用程序与数据库建立连接,使用Command对象的ExecuteScalar()方法从查询数据库获得单个值。实际工作中,我们可能会查询数据库以返回多条记录,如何获得一次查询得到的多行多列的数据值呢?我们可以使用Command对象的ExecuteReader()方法返回一个DataReader对象,通过DataReader就可以从数据库中读取多条记录了。
DataReader对象
ADO.NET的DataReader对象可以从数据源中检索只读、只进的数据流,每次从数据源中只提取一条记录。使用DataReader可以提高应用程序的运行性能,减少系统开销。DataReader属于.NET数据提供程序,每一种.NET数据提供程序都有与之对应的DataReader类。
.NET数据提供程序及其DataReader类
.NET数据提供程序 |
DataReader类 |
命名空间 |
SQL数据提供程序 |
SqlDataReader |
System.Data.SqlClient |
OLE DB数据提供程序 |
OleDbDataReader |
System.Data.OleDb |
ODBC数据提供程序 |
OdbcDataReader |
System.Data.Odbc |
Oracle数据提供程序 |
OracleDataReader |
System.Data.OracleClient |