求知若饥,虚心若愚
重写Object的成员
- ToString(),使其格式化更有意义,最好返回简短的字符串
- GetHashCode(),重写比较麻烦,但如果重写Equals就要重写GetHashCode,参考文章
- Equals(),注意判空,在使用ReferenceEquals来判断引用是否相等(只有引用类型才可能引用相等,值类型会装箱的),然后判断关键数据是否一致。默认实现只是判断了引用同一性。C#7使用元组语法简化重写过程
- GetHashCode、Equals、==、!=要一起修改(后面两个一般简单判空下即可使用Equals来支持,注意避免重载时使用改操作符,否则会无限递归)
操作符重载
1 | public static xx operator xx(xx, xx)//二元类型的话 |
引用其他程序集
- 可访问修饰符
修饰符 描述 public 凡是能访问类型的地方,都能访问类型的成员。 internal 成员只能从当前程序集中访问 private 成员可从包容类型中访问,但其他任何地方都不能访问 protected 成员可从包容类型以及任何派生类型中访问,即使派生类型在不同程序集中 protected internal 成员可从包含程序集的任何地方访问,还可从包容类型的任何派生类中访问,即使派生类不在程序集中 private protected 成员可从同一程序集中包容类型的任何派生类中访问,c#7.2添加
定义命名空间
CLR中没有“命名空间”这种东西,应该是通过拼接类型名
XML注释
- 一般和c#声明配合使用
- 可用注释生成文档
- 注释在代码提示方面很有用
垃圾回收
- 回收的是不被引用的对象占用的内存(而不是资源),目的在于提高内存使用率
- 分代,mark-and-compact算法,将还在用的内存紧挨着放并分成三代
- 建议多看几篇文章
- 弱引用,可重复利用还未被垃圾回收的对象,适用于那些生成费时费力的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14private WeakReference Data;
public FileStream GetData()
{
FileData data = (FileData)Data.target;
if(data != null)
{
return data;
}else
{
// 创建data
Data.target = data;
return data;
}
}
资源清理
- 终结器,不能手动调用,只能等对象被回收器终结时自动调用,语法与c++一致,“~”,用于清理类的资源(文件句柄,数据库连接等等),一定要避免异常,不然出了bug都不明不白(时机不确定,如果没有调用堆栈的话)
- 由于终结器执行的不确定性,c#还提供了IDisposable接口,来显示调用,最好还需要在终结器中调用这个接口,避免疏漏
- 虽然可以手动调用Dispose接口,但如果没有写异常处理函数的话还是可能没有调用到,所以可以使用using语句,只要实现了IDisposable接口,离开作用范围后会自动调用,即使发生了异常,其实原理是自动生成了try-finally语句。