C#的类和结构,静态,访问器,虚成员和抽象成员,扩展方法,操作符重载,匿名类型
在C++中,类和结构体的区别只有默认成员访问级别不同,类默认访问级别是private,而结构体是public。
在C#中,类和结构就很大不同了,从类型上看,结构是值类型,类是引用类型。下面就说一下两个类型的要点。
结构
- 因为是值类型,所以变量不能为null。
- 结构是隐式密闭的,所以不能被派生,也不能继承于类,只能实现接口。
- 结构的默认构造函数(无参构造函数)是不能在程序中声明的,也不能重定义或者删除的。但可以重载。
- 创建结构对象不一定要用new,数据成员值要先赋值才能用。
- 所有数据成员都赋值了才能使用成员函数。
- 没有析构函数。
类
构造函数(construct)
和C++构造函数要求不同,C#可以不声明或重载无参构造函数,直接声明定义有参构造函数。
析构函数(finalizer)
和C++析构函数不同,C#析构函数不会在实例超出作用域就调用。这是无法知道系统几时调用析构函数的。所以应该采用dispose模式。详见《C#图解教程》P515。
使用析构函数时一些重要的原则:
1. 不要在不需要时实现析构函数,这会严重影响性能;
2. 析构函数应该只释放对象拥有的外部资源;
3. 析构函数不应该访问其他对象,因为无法认定这些对象是否已经被销毁。
关于静态
使用静态构造函数而不是静态初始化器最常见的理由就是处理异常。在使用静态初始化器时,我们无法自己捕获异常。而在静态构造函数中却可以做到。
静态成员
结构和类都一样,常量和索引器不能声明为static。
静态构造函数
静态构造函数对于类和结构用法来说,是一样的。不存在静态析构函数。
- 只能有一个静态构造函数,而且不能带参数。
- 不能有访问修饰符。
- 不能显示调用静态构造函数,系统会自动调用,有两种情况:创建实例对象前 或者 任何静态成员被引用前。
关于访问器
get和set两个访问器在属性和索引器都有用到。
访问器的访问修饰符
- 默认情况访问器的访问级别和声明的属性或索引器的访问级别一样。
- 只有get和set访问器都有的时候,才可以修改访问器的修饰符。
- get和set访问器的修饰符只能改一个。
- 访问器的访问修饰符必须比成员的访问级别更严格的限制。
//正确案例
public string Name
{
get;
private set;
}
关于虚成员和抽象成员
WARNING!!
在构造函数中调用虚方法是极不推荐的。相当于在基类构造函数时,调用了派生类的覆写方法,也就是在派生类执行构造方法前。
关于扩展方法
操作符重载
必须声明为公有静态方法(public 和 static)。
匿名类型
类似只有变量的结构。常用于LINQ里面做查询。
- 匿名类型只能和局部变量配合使用,不能用于类成员。
- 必须用var关键字做变量类型。
- 如果编译器遇到另一个具有相同参数名,相同推断类型和相同顺序的匿名类型,它会重用这个类型并直接创建新的实例,不会创建新的匿名类型。