C#学习笔记一--C#中的参数传递

由于在 .NET 中存在两种类型,分别是值类型( value type )和引用类型( reference type ),所以很多关于 C# 中参数传递的混淆就因此而生。

首先要弄清楚的是:值类型是分配在栈( stack )上面,而引用类型分配在堆( heap )上面。栈是一种先进后出,并且由系统自动操作的存储空间。而堆(在 .NET 上准确的说是托管堆 Managed Heap )是一种自由储存区( Free Memory ),在该区域中,必须明确的为对象申请存储空间(一般在 Java 和 C #中都是使用的 new 关键字),并可以在使用完以后释放申请的存储空间( Java 和 C #都使用垃圾回收机制 Garbage Collector 自动释放对象空间)

引用类型( reference type ):它存放的值是指向数据的引用( reference ),而不是数据本身 。示例:

System.Text.StringBuilder sb = new StringBuilder();

这里,我们声明一个变量 sb ,并通过 new StringBuilder() 创建了一个 StringBuilder (与 Java 中 StringBuffer 类似)对象,再将对象的引用( reference )赋值给变量 sb ,即变量 sb 中保存的是 StringBuilder 对象的引用,而非对象本身。

System.Text.StringBuilder first = new StringBuilder();

System.Text.StringBuilder second = first;

这里,我们将变量 first 的值(对一个 StringBuilder 对象的引用)赋值给变量 second ,即 first 和 second 都指向同一个 StringBuilder 对象。对 StringBuilder 对象的任何修改都会影响到 first 和 second 变量。

System.Text.StringBuilder first = new StringBuilder();

System.Text.StringBuilder second = first;

first.Append("hello");

first = null ;

Console.WriteLine(second);

这里,输出的结果是 hello 。由于 first 和 second 都含有对同一 StringBuilder 对象的引用。然后通过 first 的引用调用 StringBuilder 对象的 Append 方法,将对象进行修改,即添加字符串“ hello ”,然后又将 first 赋值为 null ,表示让 first 不引用任何对象。最后通过 second 的引用隐式调用 StringBuilder 对象的 ToString 方法输出“ hello ”。由此可见, first 的值改变了(被赋值为 null ),而它所引用的对象并不会发生改变, second 照样引用到 StringBuilder 对象。

class 类型, interface 类型, delegate 类型和 array 类型都是引用类型。

值类型( value type ):引用类型中变量和实际数据之间还隔了一间接层,而值类型就完全不存在,值类型的变量直接保存的就是数据。

struct IntHolder

{

public int i;

}

这里,结构是值类型, IntHolder 是一个结构:

IntHolder first = new IntHolder();

first.i = 5;

IntHolder second = first;

first.i = 6;

Console.WriteLine(second.i);

输出结果为 5 。这里 second = first 以后 second 保存的是 first 的值拷贝,即 second.i = 5 ;而后来的 first.i 发生了改变并不会影响 second.i 。所以输出值为 5 。

简单类型(比如 int,double,char ), enum 类型, struct 类型都是值类型。

注意:有一些类型(比如 string 类型)的行为看起来像值类型,但实际上是引用类型。这些类型被称为 immutable 类型,也就是说这种类型的实例只要被构造好就不会改变。比如, string.Replace() 并不会改变调用它的字符串对象,而是返回含有新数据的新的字符串对象。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus