C#2008与.NET 3.5 高级程序设计读书笔记(4)--C#核心编程结构II

1.ref及out.params

ref

ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

代码
using System;

class App
{
public static void UseRef(ref int i)
{
i
+= 100;
Console.WriteLine(
"i = {0}", i);
}

static void Main()
{
int i = 10;

// 查看调用方法之前的值
Console.WriteLine("Before the method calling: i = {0}", i);

UseRef(
ref i);

// 查看调用方法之后的值
Console.WriteLine("After the method calling: i = {0}", i);
Console.Read();
}
}

/**//*
控制台输出:
Before the method calling : i = 10
i = 110
After the method calling: i = 110
*/

out

out 关键字会导致参数通过引用来传递。这与 ref 关键字类似。

与 ref 的不同之处:

  1. ref 要求变量必须在传递之前进行初始化。
  2. 尽管作为 out 参数传递的变量不需要在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。

示例

与 ref 示例不同的地方只要将 ref 改为 out,然后变量 i 仅需要声明即可。

 

static void Main()
{
//int i = 10;
改为 int i;
//
}

 

 

params

params 关键字可以指定在参数数目可变处采用参数的方法参数。params 关键字在方法成员的参数列表中使用,为该方法提供了参数个数可变的能力!

 

代码
// keywords_params.cs

using System;

class App
{
public static void UseParams(params object[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
}

static void Main()
{
// 一般做法是先构造一个对象数组,然后将此数组作为方法的参数
object[] arr = new object[3] { 100, 'a', "keywords" };
UseParams(arr);

// 而使用了params修饰方法参数后,我们可以直接使用一组对象作为参数
// 当然这组参数需要符合调用的方法对参数的要求
UseParams(100, 'a', "keywords");

Console.Read();
}
}

 2.C#变量的默认值

The member variables of class types are automatically set to an appropriate default value. This
value will differ based on the exact data type; however, the rules are simple:
• bool types are set to false.
• Numeric data is set to 0 (or 0.0 in the case of floating-point data types).
• string types are set to null.
• char types are set to '\0'.
• Reference types are set to null.

 


        class Test
        {
            
public int myInt; // Set to 0.
            public string myString; // Set to null.
            public bool myBool; // Set to false.
            public object myObj; // Set to null.
        }

 3.C#值类型与引用类型

.NET将数据类型分为值类型(value type)引用类型(reference type)

一个具有值类型(value type)的数据存放在内的一个变量中。即是在栈中分配内存空间,直接存储所包含的值,其值就代表数据本身。值类型的数据具有较快的存取速度

一个具有引用类型(reference type)的数据并不驻留在栈中,而是存储于中。即是在堆中分配内存空间,不直接存储所包含的值,而是指向所要存储的值,其值代表的是所指向的地址。当访问一个具有引用类型的数据时,需要到栈中检查变量的内容,该变量引用堆中的一个实际数据。引用类型的数据比值类型的数据具有更大的存储规模和较低的访问速度


问     题值  类  型引 用 类 型
这个类型分配在哪里? 分配在栈上 分配在托管堆上
变量是怎么表示的? 值类型变量是局部复制 引用类型变量指向被分配得实例所占的内存
基类型是什么? 必须继承自System.ValueType 可以继承自除了System.ValueType以外的任何类型,只要那个类型不是sealed的
这个类型能作为其他类型的基类吗? 不能。值类型是密封的,不能被继承 是的。如果这个类型不是密封的,它可以作为其他类型的基类
默认的参数传递是什么? 变量是按值传递的(也就是,一个变量的副本被传入被调用的函数) 变量是按引用传递(例如,变量的地址传入被调用的函数)
这个类型能重写System.Object.Finalize()吗? 不能。值类型不好放在堆上,因此不需要被终结。 可以间接地重写
我可以为这个类型定义构造函数吗? 是的,但是默认的构造函数被保留(也就是自定义构造函数必须全部带有参数) 当然!
这个类型的变量什么时候消亡? 当它们越出定义的作用域时。 当托管堆被垃圾回收时。

 

托管堆的概念:

1 这些都是.NET中CLR的概念,和C#没多大关系。 
2 使用基于CLR的语言编译器开发的代码称为托管代码。 
3 托管堆是CLR中自动内存管理的基础。初始化新进程时,运行时会为进程保留一个连续的地址空间区域。这个保留的地址空间被称为托管堆。托管堆维护着一个指针,用它指向将在堆中分配的下一个对象的地址。最初,该指针设置为指向托管堆的基址。 
posted @ 2010-06-28 11:57  自助者天助  阅读(198)  评论(0编辑  收藏  举报