1. 常用的CIL指令
BOX: value type和reference type之间的转换
CALL: 调用方法,如果方法是虚拟的,虚拟性被忽略
CALLVIRT: 调用方法,如果方法是虚拟的,虚拟性不被忽略
CASTCLASS: 将对象转换为另一种类型
LDC: 向堆栈中加载数值常量
LDARG[A]: 向堆栈中加载参数或参数地址[A]
LDELEM: 向堆栈中加载数组元素
LDLOC[A]: 向堆栈中加载局部变量或者局部变量地址[A]
LDSTR: 向堆栈中加载字符串
NEWARR: 创建新数组
NEWOBJ: 创建新对象
RET: 从方法调用中返回
STARG: 将堆栈中的值复制到参数中
STELEM: 将堆栈中的值复制到数组元素中
STLOC: 将堆栈中的值传递给局部变量
THROW: 引发异常
UNBOX: 将引用类型转换为值类型
2. Reference type通过class进行定义,位于GC管理的堆中,并通过抽象底层指针的引用进行访问。Value type通过struct定义,位于堆栈中。Value type即使使用new来定义,也在堆栈上创建,同时Value type不能从其他类型派生,但是可以从interface派生,它们不应该包装非托管资源。尽管Value type继承了Finalize方法,但GC忽略在堆栈中创建的对象,因而永远不会调用该方法。
3. 委托通常用来定义响应事件的回调方法的签名。如Timer类的定义:
public delegate void ElapseEventHandler(Object sender, ElapsedEventArgs e);
public class Timer
{public event ElapseEventHandler Elapsed; … }
Timer触发事件:
if(Elapsed != null) Elapsed(this, new ElapsedEventArgs(…));
客户使用Timer对象,60s调用一次UpdateData方法:
Timer timer = new Timer(60000);
timer.Elapsed += new ElapsedEventHandler(UpdateData);
void UpdateData(Object sender, ElapsedEventArgs e){…}
在实践中,delegate关键字只是下列程序的别名:
public class ElapsedEventHandler : MulticastDelegate
{
public ElapsedEventHandler(object target, int method){…}
public virtual void Invoke(object sender, ElapsedEventArgs e){…}
}
4. 非确定销毁(NDD)有两个规则可以避免:(1)针对使用封装文件等非托管资源的类,直接使用Close或Dispose方法释放或关闭资源。(2)实现一个带有Boolean参数的protected的Dispose方法,如果传递的参数是true,则在该函数中对所有资源进行Dipose或者Close;实现IDisposable接口,它包含一个不含参数的Dispose方法,在这个函数中调用GC.SuppressFinalize来避免GC调用Finalize,然后调用protected的Dispose函数并传递true的参数;重写Finalize函数,调用protected的Dispose函数并传递false;代码如下:
class File:IDisposable
{
~File() {Dispose(false);}
public void Dispose(){GC.SuppressFinalize(this); Dispose(true);}
protected virtual void Dispose(bool disposing)
{
if (disposing){释放资源}
}
public void Close(){Dispose();}
}
5. 创建多文件的Assembly使用AL,例如al /target:library /out:math.dll simple.netmodule complex.netmodule;其中netmodule文件可以使用编译器指定target为module链接。生成的文件math.dll包含了一个manifest,这个manifest中包含了各文件的信息。
6. 对应用程序进行配置,通常生成一个config文件,其文件名为应用程序名称加上”.config”。如指定probing的privatePath可以指定偏移路径。
7. 创建强名称的Assembly,首先生成Key文件,使用SN(例如 sn /k KeyFile.snk)。再使用AL来生成,增加/keyfile来指定Key文件,增加/version来指定版本。强名称的Assembly系统会校验版本信息,并对各文件的Hash进行校验。想替换新版本的强名称的Assembly,可以使用config文件中的dependentAssembly项,其所需要的pulicKeyToken可以使用sn /t math.dll来获得。
8. 全局程序集缓存(GAC),只有强名称的Assembly才可以被安装到GAC中,可以使用GACUTIL来安装和卸载Assembly。
9. 可以通过属性来创建强名称的Assembly。如C#可以使用[assembly:AssemblyKeyFile (“Keyfile.snk”)]来指定Key文件。
10. 可以通过延迟签名来实现没有密钥的Assembly,使用AL的/delaysign或者属性[assembly:DelaySign (true)]。在正式发布的时候需要使用密钥真正签名,使用sn /R math.dll keyfile.snk。延迟签名的Assembly无法安装到GAC中,为了启用这些功能,必须使用sn /Vr math.dll跳过版本验证。真正发布时候使用sn /vu math.dll来禁止跳过验证。
11. FCL中读写文件一般使用FileStream对象打开文件,如果是二进制读写,使用BinaryReader和BinaryWriter类包装FileStream;如果是文本读写,则使用StreamReader和StreamWriter。
12. 使用System.Text中的ASCIIEncoding可以将字符串转换为字节数组,如下代码:
ASCIIEncoding enc = new ASCIIEncoding(); byte [] keybytes = enc.GetBytes(key);
13. System.Collections中的所有集合类(除BitArray)都是弱类型,也就是它们存储的是System.Object的实例,优点是能够存储所有类型的数据;缺点是必须进行多次转换。强类型可以使用CollectionBase和DictionaryBase基类。
14. Hashtable将添加的项存储在System.Collections.DictionaryEntry对象中,DictionaryEntry对象存储由Key和Value属性公开。由于Hashtable实现了IDictionary接口,这一接口间接从IEnumerable派生,所以可以使用C#的foreach。
15. 当Hash表增长时,她总是把容量假定为一个质数以减少发生冲突的可能性,可以通过改变加载因子(load factor)来控制这一百分比。默认情况下,Hashtable通过使用键的GetHashCode方法来获得Hash输入键。可以使用(1)重写派生类的GetHashCode,并提供一个生成唯一Hash的方法;(2)创建一个IHashCodeProvider的类型,并把该类型的一个实例传给Hashtable的构造方式,Hashtable将将调用该对象的GetHashCode。Hashtable调用键的Equals方法来比较键,可以重写派生类的Equal方法或者实现一个IComparer接口的实例,并把它传给Hashtable的构造函数。
16. System.Text.RegularExpressions命名空间,Regex.Split使用表达式来标识分隔符,将字符串拆分为一致的部分。例如拆分路径:
Regex regex = new Regex(@”//”); // @禁止转义
string [] parts = regex.Split(@”C://inetput//wwwroot//wintellect”);
foreach(string part in parts) Console.WriteLine(part);
分析HTML格式文件:Regex regex = new Regex(“<[^>]*>”);
17. Regex查询字符串中匹配特定模式的子字符串。主要使用Match、Matches和IsMatch方法。IsMatch判断输入字符串是否包含由正则表达式指定的字符。如校验字符串包含16个数字并且4个1组,代码:Regex regex = new Regex(“^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$”);其中^和$表示一行的开始和结束。可以使用”/d”来代替[0-9]。正则表达式中原义符”s”表示空白,因而”/s*”表示任意数目的连续空白字符。如查找HTML中href项:”href//s*=//s*/”[^/”]*/””;可以使用Match.NextMatch进行多次查找。如下代码:
for(Match m= regex.Match(line); m.Success; m=m.NextMatch()){…}
使用Matches函数改写为:
MatchCollection matches=regex.Matches(line);
foreach(Match m in matches){…}
Match对象包含一个Groups属性,允许标志匹配中的字符串,Groups[0]标志匹配的完整文本,Group[1]标识括号中的匹配的子集。如href的查找中发现href=”dotnet.html”;则Value和Groups[0]都为href=”dotnet.html”;而Groups[1]为dotnet.html。
18. System.Net命名空间包括Internet相关的任务,最有用的类是WebRequest和WebResponse类。而从他们派生的HttpWebRequest和HttpWebResponse则处理了Http的资源。如:
WebRequest request= WebRequest.Create(http://www.microsoft.com);
WebResponse response=request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream);…
19. System.Web.Mail为SMTP提供了一个简单的接管接口。核心类是MailMessage、MailAttachment和SmtpMail。