CH 6

参数数组: 只能放在函数定义的最后。

1
2
3
4
5
6
7
8
9
void foo(params int[] vals)
{
foreach(var val in vals)
{
// ...
}
}

foo(1, 2, 3, 4);

引用参数: ref。必须在函数中使用非常量变量;变量必须初始化过。

1
2
3
4
5
6
7
void foo(ref int val)
{
// ...
}

int a = 0;
foo(ref a);

输出参数: out。变量可以未赋值;在使用out参数时,必须把它看成是尚未赋值。

1
2
3
4
5
6
7
8
void foo(out int val)
{
val = 1;
// ...
}

int a;
foo(out a);

委托(delegate): 存储函数引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
delegate double FuncDelegate(double a, double b);

double foo(double a, double b)
{
// ...
}

double bar(double a, double b)
{
// ...
}

FuncDelegate fd;

fd = new FuncDelegate(foo); // fd = foo;
fd(1.0, 2.0);

fd = new FuncDelegate(bar); // fd = bar;
fd(3.0, 4.0);


CH 7

try…catch…finally: 可以只有try块和finally块或有一个try块和好几个catch块;如果有一个或多个catch块,finally可选,否则就是必须的。


CH 8

通过把默认构造函数设置为私有的,可以强制类的用户使用非默认的构造函数。

UML中,类的静态成员带有下划线。

静态构造函数: 为静态成员提供初始化操作。一个类只能有一个静态构造函数,构造函数无访问修饰符和任何参数。静态函数在下列情况被调用

  • 创建包含静态构造函数的类的实例时。
  • 访问包含静态构造函数的类的静态成员时。

静态类: 只包含静态成员,不能包含实例构造函数,可以有一个静态构造函数。

可删除的对象: 支持IDisposable接口,必须实现Dispose()方法,当不再需要对象时,Dispose()方法被调用,资源得到释放,否则会等到垃圾回收调用析构方法时才会释放资源。

using关键字可以在代码块中初始化使用重要资源的对象,在代码块的末尾会自动调用Dispose()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
<ClassName> <VariableName> = new <ClassName>();
// ...
using (<VariableName>)
{
// ...
}

// or

using (<ClassName> <VariableName> = new <ClassName>())
{
// ...
}

值类型总是包含一个值,引用类型可以是null。


CH 9

类的访问级别:internal(默认)、public

抽象类(abstract class): 不能实例化、只能继承、可以有抽象成员。

密封类(sealed class): 不能继承。

继承

1
2
3
4
5
6
7
8
9
public class MyBase
{
// ...
}

public class Myclass: My Base
{
// ...
}

编译器不允许派生类的可访问性高于基类。

接口的声明必须更在基类后面。

接口访问级别和类相同;不能在接口中使用关键字abstractsealed,没有意义。

GetType(): 返回对象类型。

typeof: 运算符,把类名转换为System.Type对象。

.NET中使用的析构函数称为Finalize()

在初始化器中指定基类构造函数

1
2
3
4
5
6
7
8
public class MyClass: Base
{
// ...
public MyClass(int i, int j): base(j)
{
// ...
}
}

在初始化器中调用其他构造函数

1
2
3
4
5
6
7
8
public class MyClass: Base
{
// ...
public MyClass(int i, int j): this(j)
{
// ...
}
}

接口成员是public的,抽象类成员可以是private(只要不是抽象的)、protected、internal、protected internal(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。接口不能包含字段、构造函数、析构函数、静态成员或常量。

对象的赋值是引用操作,结构的赋值是值拷贝。


CH 10

.NET Framework中的公共字段以PascalCasing形式命名,私有字段通常以camelCasing来命名。

readonly: 只能在执行构造函数的过程中或者初始化赋值语句赋值。

const成员也是静态的,不需要static修饰符。

类成员方法可以使用的关键字:

  • virtual: 方法可以重写
  • abstract: 方法必须在非抽象的派生类中重写
  • override: 方法重写了一个基类方法
  • extern: 方法定义放在其他地方

如果使用了override,也可以使用sealed来指定在派生类中不能对这个方法做进一步的修改。

1
2
3
4
public override sealed void foo()
{
// ...
}

使用extern可以在项目外部提供方法的实现代码。

属性: 访问器get&set,至少包含一个,属性才是有效的。

1
2
3
4
5
6
7
8
9
10
11
12
13
private int myInt;

public int MyIntProp
{
get
{
return myInt;
}
set
{
myInt = value;
}
}

属性可以使用vitualoverrideabstract关键字。访问器的可访问性不能高于它所属的属性。

自动属性

1
2
3
4
5
public int MyIntProp
{
get;
private set;
}

隐藏基类方法

1
2
3
4
5
6
7
public class MyDerivedClass: Base
{
new public void foo()
{
// ...
}
}

重写基类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Base
{
// ...
public virtual void foo()
{
// ...
}
}

public class Derived: Base
{
// ...
public override void foo()
{
// ...
}
}

base关键字调用基类方法(非静态成员中使用)。

接口

  • 不允许使用访问修饰符,所有接口都隐式地是公共的。
  • 接口成员不能包括代码体。
  • 接口不能定义字段成员,可以定义属性。
  • 不能用关键字static、virtual、abstract、或sealed来定义接口成员。
  • 类型定义成员是禁止的。(?)

部分类、部分方法: partial