/// <summary>
/// 第八章:理解值和引用
/// </summary>
namespace Chapter8
{
class Program
{
static void Main(string[] args)
{
//8.1复制值类型的变量和类
int i = 42;
int copyi = i;
i++;
//i和copyi是两个地址互不影响
Mouble.Circle C;
C = new Mouble.Circle(42);
Mouble.Circle refc = C;
//new出来是同一地址
//复制引用的错误方式:refc.v = C.v;
//运用克隆的方法复制数据
//8.2理解null值和可空类型
/*
* 变量要初始化
* 类可以为null
*/
///8.2.1 空条件操作符
if(C is null)
{
}
///8.2.2 使用可空类型
//非法 int i = null
int? itest = null;//合法
///8.2.3 理解可控类型的属性
if (!itest.HasValue)//itest为空
{
itest = 99;
}
else
{
Console.WriteLine(itest.Value);
}
//8.3 使用ref参数和out参数
///8.3.1创建ref参数
int arg = 42;
doIncrement(ref arg);
Console.WriteLine(arg);//为43
///8.3.2创建out参数
int arg1;//未初始化
doInitialize(out arg1);
Console.WriteLine(arg1);
//8.4计算机内存的组织方式
/*
* 栈:
*
* 设计的目标:调用方法时,它的参数和局部变量分配的内存总是从栈中获取。
* 方法结束后(不管正常返回还是抛出异常),为参数和局部变量分配的内存都自动归还给栈,并可在另一个方法调用时重新使用。
* 栈上的方法参数和局部变量具有良好定义的生存期。
* 方法开始时进入生存期,结束时结束生存期。
*
* 内存管理方式(堆的越来越高的箱子):调用方法时,它的每个参数都被放入一个箱子并放到栈顶。
* 每个局部变量也同样分配到一个箱子,并同样放到栈顶。
* 方法结束后,它的所有箱子都从栈中移除。
*
* 堆:
*
* 设计的目标:使用new关键字创建对象(类的实例)时,构造对象所需的内存总是从堆中获取。
* 堆上创建的对象具有较不确定的生存期;
* 使用new关键字将创建对象,但只有在删除了最后一个对象引用之后的某个不确定时刻,它才会真正消失。
*
* 内存管理方式(散步在房间里的一大堆房子):创建新对象时,“运行时”查找空箱子,把它分配给对象。
* 对对象的引用则存储在栈上的一个局部变量中。
* “运行时”跟踪每一个箱子的引用数量(记住,两个变量可能引用同一个对象)。
* 一旦最后一个引用消失,运行时就将箱子标记为“未使用”。
* 将来某个时候,会清楚箱子里的东西,使之能被重用。
*/
///8.4.1使用栈和堆
/*
* 虽然对象本身存储在堆中,但对象引用(变量c)存储在栈中
* 堆内存是有限的资源。堆内存耗尽,new操作符抛出OutOfMemoryException,对象创建失败。
*/
///8.4.2System.Object类(所有类都是object的派生类)
///8.4.3装箱
/*
* 将数据项从栈自动复制到堆的行为成为装箱
*/
///8.4.4拆箱
int i1 = 42;
object o = i1;
i1 = (int)o;
/*
* 编译器发现指定了类型int,所以会在运行时生成代码检查o实际引用了什么。它可能引用任何东西。
* 如o真的引用了一个已装箱int,转型成功执行,编译器生成的代码会从装箱的int中提取出值。
* (将装箱的值在存回i1)
* 该过程称为拆箱或取消装箱
*/
//8.5 数据的安全类型
///8.5.1 is操作符
if(o is int)
{
int temp = (int)o;//转是安全的:o确定是一个int型
}
///8.5.2 as操作符
String a = "aa";
String tewmp1 = a as String;
//运行时尝试将对象转换成指定类型。若转换成功,就返回转换成功的结果。
//转换失败,as表达式的求值结果为null
///8.5.3复习switch语句
Console.ReadLine();
}
static void doIncrement(ref int param)//验证是否初始化
{
param++;
}
static void doInitialize(out int param)//必须在方法中赋值,所以不用初始化
{
param=42;
}
}
}
namespace Chapter8.Mouble
{
class Circle
{
private int v;
public Circle()
{
}
public Circle(int v)
{
this.v = v;
}
//克隆复制私有数据
public Circle Clone()
{
Circle clone = new Circle();
clone.v = this.v;
return clone;
}
}
}