方法
实例构造器和类(引用类型)
构造器是将类型的实例初始化为良好状态的特殊方法,在方法定义元数据表种始终叫做.ctor。
创建引用类型的实例会:
1 为实例的数据字段分配内存
2 初始化对象的附加字段(类型对象指针和同步块索引)
3 调用类型的实例构造器来设置对象的初始状态。
实例构造器无法被继承。默认定义一个无参构造器。
如果类为abstract,默认构造器的可访问性为protected。
如果基类没有提供无参构造器,派生类必须先是调用一个基类构造器。
如果类为static,则不会在类中生成默认构造器。
实例构造器和结构(值类型)
CLR总是创建值类型的实例。值类型不需要定义构造器。
值类型允许定义构造器,但必须显示调用才会执行。
C#不允许为值类型定义无参构造器。
类型构造器
又称为静态构造器、类构造器、类型初始化器。可以应用于接口、引用类型、值类型。
类型构造器永远没有参数。
类型构造器必须标记为static,并且总是私有。
类型构造器代码中只能访问类型的静态字段,常规用处即是用于初始化这些字段。
操作符重载方法
CLR规范要求操作符重载方法必须是public和static的。1
2
3
4public seled class Complex {
public static Complex operator+ (Complex c1, Complex c2) { ... }
public static Complex Add(Complex c1, Complex c2) { return (c1+c2); }
}
转换操作符方法
如果源类型或目标类型不是基元类型,编译器会生成代码,要求CLR执行转换(强制转型)。
转换操作符是将对象从一种类型转换成另一种类型的方法。
CLR规范要求转换操作符方法必须是public和static的。
C#要求参数类型和返回类型至少有一个与定义转换方法的类型相同。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27public seled class Rational {
// 由一个Int32构造一个Rational
public Rational(Int32 num) { ... }
// 由一个Single构造一个Rational
public Rational(Single num) { ... }
// 将一个Rational转换成一个Int32
public Int32 ToInt32() { ... }
// 将一个Rational转换成一个Single
public Single ToSingle() { ... }
// 由一个Int32隐式构造并返回一个Rational
public static implicit operator Rational(Int32 num) {
return new Rational(num);
}
// 由一个Single隐式构造并返回一个Rational
public static implicit operator Rational(Single num) {
return new Rational(num);
}
// 由一个Rational显示返回一个Int32
public static explicit operator Int32(Rational r) {
return r.ToInt32();
}
// 由一个Rational显示返回一个Single
public static explicit operator Subgke(Rational r) {
return r.ToSingle();
}
}
在C#中,implicit关键字告诉编译器为了生成代码来调用方法,不需要再源代码中进行显示转型。explicit关键字告诉编译器,只有再发现了显示转型时,才调用方法。
扩展方法
允许定义一个静态方法,并用实例方法的语法来调用。
public static class StringBuilderExtensions{
public static Int32 IndexOf(this StringBuilder sb, Char value){
for(Int32 index = 0; index < sb.Length; index++)
if(sb[index] == value) return index;
return -1;
}
}
扩展方法的附加规则和原则:
- C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符等。
- 扩展方法必须在非泛型的静态类中声明。扩展方法至少有一个参数,并且只有第一个参数能用this关键字标记。
- C#编译器在静态类中查找扩展方法时,要求静态类本身必须具有文件作用于。(不能是嵌套类)
- 多个静态类可以定义相同的扩展方法。
- 一个扩展方法扩展一个类型的同时也扩展了派生类。
- 扩展方法可能存在版本问题(后续版本添加了对应的实例方法)。
扩展方法实际是对一个静态方法的调用。
分部方法
internal sealed partial class Base{
// 分部方法声明
partial void OnNameChanging(String value);
}
// 另一个源代码文件
internal sealed partial class Base{
partial void OnNameChanging(String value){
// ...
}
}
分部方法的规则和原则:
- 只能再分部类或结构中声明
- 分部方法返回类型始终未void,任何参数都不能用out修饰符来标记。
- 分部方法可以有ref参数,可以是泛型方法,可以是实例或静态方法,可以标记未unsafe。
- 分部方法的声明和实现必须具有完全一直的签名。
- 没有对应的实现部分,就不能在代码中创建一个委托来引用这个分部方法。
- 分部方法总是被视为private方法。