C#随笔
1.只读字段和常量数据
只读字段是由readonly关键字修饰的变量,和常量不同的是,它是可以运行时赋值的,但是赋值操作只能发生在定义改变量类的构造函数里。
如果是静态的只读字段且编译时就知道其值得话,那么他的定义方式就非常类似常量,否则就只能在该类的静态构造函数中赋值。
2.常量
常量是隐式静态的,常量数据一定不可以用static来修饰
3.属性的内部表示
C#的属性最终会映射到一个get_Name()/set_Name()的函数对,所以如果你自己同时定义了一个形如get_Name()或set_Name()的函数,将引发编译错误
4.非嵌套类不可定义为private
5.c#特殊的访问修饰符
internal 当前程序集可访问
protected internal 当前程序集,类型和派生类可访问
6.静态构造函数
一个类只能定义一个静态构造函数
静态构造函数不能跟类似public这样的访问修饰符,也不能带参数
静态构造函数只执行一次,发生在第一次创建该类的实例或者访问静态成员之前,且先于其他实例构造函数执行
7.this关键字的一种用法:串联构造函数
如
class A
{
private int a;
public A()
:this(0)
{}
public A(int a)
{
this.a = a;
}
}
8.可空类型
C#中值类型是不可赋空值的,但是在某些情况下我们需要对值类型赋空值,这样的话就必须引入新概念可空类型,可空类型是按如下方法定义的:
bool? a = null;
?后缀是实际上泛型System.Nullable<T>的简化表示。可空对象可以通过HasValue属性判断其是否有值。
??运算符是在可空对象为空时对其进行赋值操作,如:
int? a = getvalue() ?? 100;
这样一旦getvalue()函数返回空就会给a赋为100
9.值类型的特点
分配在栈上
必须派生自System.ValueType
是隐式密封的,不能被派生
自定义的构造函数必须有参数,因为默认构造函数会被保留
值类型不可重写System.Object.Finalize()方法,是因为值类型不会分配在堆上,所以不会被终结
值类型在离开作用域时自动被回收
10.params修饰符
params修饰符可以把多个参数作为一个数组传给函数,如:
void A(params int[] values)
{
......
}
A(1,2,3,4);
11.seales关键字,声明类不可被继承,所有的值类型(包括结构体)都是隐式sealed的
sealed也可限定虚方法不可被重写
12.虚方法重写必须使用override关键字声明
13.在抽象类中子类重写虚方法不是必须的,所以如果你的某个方法必须被重写的话,你需要定义该方法为抽象的,即用abstract来修饰该方法
public abstract void A();
抽象方法必须用在抽象类中,否则会产生编译错误
14.new关键字可以用来显示隐藏父类的版本如:
public new void A();
那么父类中的public void A()函数被隐藏,当然父类中被隐藏的方法,仍然可以通过强制转换为父类类型进行访问
15.超级父类System.Object
可以使用的有用的方法MemberwiseClone(),该方法可以逐个成员返回当前对象副本,可以用于克隆对象.
静态方法Equals来检测两个值对象的是否相等
静态方法ReferenceEquals用来检测两个引用对象,是否引用的是同一块内存数据
16.创建一个引用对象,对象保存在托管堆里,但是引用本身保存在栈中
17.强制垃圾回收
GC.Collect(0) //只回收第一代
GC.WaitForPendingFinalizers() // 挂起线程,等待垃圾回收完成
Collect还可以带GCCollectionMode作为第二参数,Force表示立即回收,Optimized表示检测当前时间是否合适回收,Default默认为Force
GC.GetTotalMemory()返回当前分配在托管堆上的估计的内存数量(字节单位)
18.Finalize()方法
Finalize()方法是在GC.Collect()中自动执行的,用来释放对象的资源,通常的对象不需要重写Finalize(),因为一般对象都是托管的,但是一旦对象中使用了非托管资源,我们就可能需要重写该方法来,释放非托管资源了。
重写Finalize()方法的唯一原因是C#类通过PInvoke或者复杂的COM互操作性任务使用了非托管资源(典型的情况是通过System.Runtime.InteropServices.Marshal类型定义的各成员)
重写Finalize()方法不能使用语法形如:protected override void Finalize(),而必须使用隐式的写法形如:
class A
{
~A()
{
}
}
19.IDispose接口和using关键字
IDisoposable接口和Finalize不同,他是显示调用的,一般来说如果类实现了IDisposable接口,你就总可以调用Dispose()函数。
当退出using作用域时,会自动调用类的Dispose()。如果没实现IDisposable接口,是不能被using的
using也可以使用多个类的实例,形如:
using(A a=new A(), B b = new B())
{
}
20.yield关键字是用来像foreach指定返回值的
21.ICloneable接口
MemberwiseClone()是protected的,所以不能直接访问,而且MemberwiseClone是浅复制,他无法处理引用类型的实例的复制

浙公网安备 33010602011771号