1.C#的文档注释,以“///”开头,可以应用于任何用户定义的类型或成员,这些注释包括内嵌XML标签或描述文本。其中标签可以用来标记描述文本,从而更好地定义类型或成员的语法。这些注释可以在编译时提取成一个单独的文档输出文件。编译器验证注释是否内在一致,将互相参考扩展为全限定类型ID,并输出良构的XML文件,进一步就是通过XSLT由XML生成HTML文档。
2.C#程序也依赖与.NET框架中的服务,如基类库(BCL)和公用语言运行时运行(CLR)。
3.C#中可以为类型定义一个特殊的运行时自动调用:静态构造函数
例如:
class A
{
public A(string text)
{
Console.WriteLine(text);
}
}
class B
{
static A a1 = new A("a1");
A a2 = new A("a2");
static B()
{
a1 = new A("a3");
}
public B()
{
a2 = new A("a4");
}
}
class Program
{
static void Main(string[] args)
{
B b = new B();
}
}
此实例先执行B的静态构造函数,执行之前先初始化类型的静态变量,再执行函数体语句,所以先打印a1,然后是a3,执行B b = new B();先初始化成员变量再调用构造函数 则顺序应该是a1,a3,a2,a4
4.对于构造函数,有一些特殊,它不能被继承,只能被调用。对于调用父类的构造函数,可以用base关键字
5.接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合,一旦类实现了接口,类就可以支持接口所指定的所有属性和成员
接口不能实例化;不能有构造方法和字段;不能有修饰符;不能声明虚拟的或静态的
实现接口的类就必须要实现接口中的所有方法和属性
6.C#有个垃圾收集器,来处理处理内存管理的工作,主要是值数据类型(用堆栈)和引用数据类型(托管堆)。
托管堆是进程的可用4GB中的另外一个内存区域new出来的实例懂放在堆中,然后把地址存放在栈中,堆栈是由高地址向低地址存放数据,堆是由低地址向高地址存放数据
.NET运行库保存了堆的状态信息(即在堆中的对象的引用次数),在堆中添加新数据时,这些信息也需要更新,当两个引用变量都指向同一对象变量时,其中一个超出作用域,不会的使对象的数据保留在堆中,只有在该数据不再被任何变量引用,才会释放。不然只能到程序停止或者垃圾收集器来处理。
垃圾收集器:当处理时,会在堆中删除不再引用的所有对象,完成后,堆会把对象分散开来,与已经释放的内存混合在一起,然后再进行压缩其他对象,将他们移动回堆的端部,再次形成一个连续的块。(当然垃圾收集器会处理堆栈中引用堆中对象的地址信息)。注意压缩一词只在托管堆中存在,未托管的堆是不会压缩其他对象的,它的释放如下红色字体。
因为基于堆的对象的生存期与引用它们的基于堆栈的变量的作用域不匹配,所以要使得堆中的数据跟堆栈一样连续存放时很困难的
垃圾收集器:不会释放未托管的资源(例如文件句柄,网络连接和数据库连接),这些需要专门的规则,C#一共有两种机制“
(1)声明一个析构函数(或终结器),作为类的一个成员
在垃圾收集器删除对象之前,可以调用析构函数,释放未托管的资源,可以放入其中
注意垃圾收集器不知道析构函数什么时候执行,所以不能在析构函数中放置需要某时刻运行的代码
(2)在类中实现System.IDisposable接口:为释放未托管的资源提供了确定的机制,IDisposable接口声明了一个方法Dispose(),不带参数,无返回值
class Myclass:IDisposable
{
public void Dispose()
{
//implementation
}
}
例如一个类ResoourceGobbler使用某些外部资源要释放应该如下使用
ResourceGobbler the Instance = new ResourceGobbler();
//do your processing
theInstance.Dispose();
但是这样如何在do your processing中出现异常,则连接没有释放,所以应该用try{}finally如下
ResourceGobbler theInstance = null;
try
{
theInstance = new ResourceGobbler();
//do your processing
}
finally
{
if(theInstance != null)
theInstance.Dispose();
}
C#中也一共了一种同样的方式
using(ResourceGobbler theInstance = new ResourceGobbler())
{
//do your processing
}
(3)最好的是将析构函数和IDisposable联系起来使用,详情参见C#高级编程