} 细节25泛型 细节26包含/委托 类似适配器模式,把类中定义对象,然后自定义方法,然后在方法体中用到定义的对象中的方法。 细节27实现迭代器 迭代器是可以返回相同类型值的有序序列的一段代码,可用做方法、运算符或get访问器的代码体。可以在类中实现多个迭代器,每个迭代器都必须像类成员一样有唯一的名称。并且可以再foreach语句中被客户端代码调用。迭代器的返回类型必须为IEnumerable或IEnumerator中任意一种,也可以是实现这两个接口的类。 IEnumerable接口:包含了。net框架用于从对象中提取元素的方法。如果类包含一个元素的集合,并希望其他代码段使用foreach循环语句遍历该集合中的每一个元素则应该在类上实现该接口。 IEnumerable接口值包含一个方法定义GetEnumerator(),用于返回一个循环访问集合的枚举数。 IEnumerator接口:支持对非泛型集合的简单迭代。该接口定义了一个属性和两个方法 1.Object Current{get}属性,获取集合中的当前元素 2.bool MoveNext()方法,访问集合的下一个元素 3.void Reset()方法,设置枚举数为其初始位置。 使用时必须引用System。Collection命名空间 public class Car : IEnumerable, IEnumerator { private short flag = -1; public IEnumerator GetEnumerator() { return this; } public object Curretn { get { switch (flag) { case 0: return "aodi"; case 1: return "huangguan"; default : return "this is Error"; } } } public bool MoveNext() { flag++; if(flag ==2) { return false; } return true; } public void ReSet() { flag = -1; } } static void Main(string[] args) { Car car = new Car(); foreach (string s in car) { Response.Write(s+"</br>"); } } 使用C#中的yield return命令也可以实现迭代器 细节28压缩和解压缩流的方法 在。net中,systtem.Io.Strem 类是所有流类型的虚基类。操作文件的FileStrem,操作内存的MemoryStrem操作网络的NetworkStrem Stream类的Read()方法用于从当前流中读取字节序列。 public abstract int Read() { byte[] buffer,//字节数组 int offset,//表示从开始读取的位置 int count//读取的最大字节数 } Stream类的Write()方法用于从当前流中写入字节序列。并返回写入的字节数 public abstract int Write() { byte[] buffer,//字节数组 int offset,//表示从开始写入的位置 int count//写入的字节数 } 一般情况下,对文件或数据可以进行压缩或解压缩操作。实质上就是对流的操作。在。net框架的System.IO.Compression命令空间下提供了GZipStream类,可以实现对流的压缩和解压缩。 public GZipStream ( Stream stream;//要压缩或解压缩的流 CompressionMode mode;//要采取的操作(Compress压缩流或Decompress解压缩流) bool leaveOpen (true表示将流保留为打开状态,false表示流为关闭状态) ) //定义一个用于读取指定数据流中的数据的方法 private const int bufferlength=1024; public static Byte[] ReadBytes(Stream stream, int bufferlength) { Byte[]buffer=new Byte [bufferlength ]; List<Byte> data = new List<Byte>(); int real; while ((real = stream.Read(buffer, 0, bufferlength)) > 0) { if (real < bufferlength) { Byte[] temp = new Byte[real]; Array.Copy(buffer, temp, real); data.AddRange(temp); } else { data.AddRange(buffer ); } } return data.ToArray(); } //定义一个向当前流中写入字节数组数据 public static void WriteBytes(Stream stream, Byte[] data, int bufferlength) { Byte[]buffer=new Byte[bufferlength ]; for (long g = 0; g < data.LongLength; g += bufferlength) { int le = bufferlength; if (g + bufferlength > data.LongLength) { le=(int)(data.LongLength -g); } Array.Copy(data,g,buffer,0,le ); stream.Write(buffer,0,le ); } } //自定义方法压缩流,并调用前面定义的方法 //压缩字节数据 public Byte[] CompressByte(Byte[] data) { using (MemoryStream ms = new MemoryStream()) { //提供压缩内存流的方法 using (System.IO.Compression.GZipStream gs = new System.IO.Compression.GZipStream(ms, CompressionMode.Compress, true)) { WriteBytes(gs,data,bufferlength );//将数据写入压缩流 } return ms.ToArray();//返回压缩后的数据 } } //自定义方法解压缩流 public static Byte[] DeCompressByte(Byte[] data) { using (MemoryStream ms = new MemoryStream(data ))//数据存于内存流 { //提供解压缩的方法 using (System.IO.Compression.GZipStream gs = new System.IO.Compression.GZipStream(ms, CompressionMode.Decompress, true)) { return ReadBytes(gs, bufferlength);//读取解压缩流中的数据 } } } 细节29C#中的深复制和浅复制 浅复制是指复制一个对象的时候,复制原始对象中所有的非静态值类型成员和所有的对应类型成员的引用 深复制是指不仅仅复制所有的非静态值类型成员,而且还复制所有引用类型成员的实际对象。 细节30全角字符转换为半角 全角字符是指一个字符占用两个标准字符位置。 半角字符是指一个字符占用一个标准字符的位置。 //判断字符是否英文半角字符或标点 public static bool IsHalflChar(char c) { int i = (int)c; return i >= 32 && i <= 126;
} //判断字符是否全角或标点 public static bool IsAllChar(char c) { if(c=='\u3000')return true ; int i =(int )c-65248; if (i < 32) return false; return IsHalflChar((char)i);
} //将字符串中的全角字符转换和为半角 public static string aToh(string s) { if(s==null ||s.Trim ()==string.Empty )return s; StringBuilder sb = new StringBuilder(s.Length ); for (int i = 0; i < s.Length; i++) { if (s[i] == '\u3000') { sb.Append('\u0020'); } else if (IsAllChar(s[i])) { sb.Append((char)((int)s[i] - 65248)); } else sb.Append(s[i]); } return sb.ToString(); } 细节31分析路径字符串函数总结 相对路径:指相对对于网站地址的文件路径。 绝对路径:指磁盘上的一个指定位置。 C#中通过Path类的相关方法可以分析路径字符串。 GetDirectoryName:返回指定路径字符串的目录信息 GetExtension:返回指定的路径字符串的扩展名 GetFullPath:返回指定路径字符串的绝对路径 GetPathRoot:获取指定路径的根目录信息 HasExtension:确定路径是否包含文件扩展名 IsPathRooted:获取一个值,该值指示指定的路径字符串是包含绝对路径信息true还是包含相对路径信息false。 //分析路径字符串 protected void FenSi() { string str = string.Empty; string path1 = "c:\\temp\\blog.txt"; string path2 = @"c:\\temp\\blog"; string path3 = @"Record"; if (Path.HasExtension(path1)) { str = string.Format("路径{0});下有一扩展名为{1}的文件,属于目录{2}", path1, Path.GetExtension(path1), Path.GetDirectoryName(path1 )); } if (Path.IsPathRooted(path2)) { string.Format("路径{0}的根目录为{1}",path2 ,Path .GetPathRoot (path2)); } str = string.Format("路径{0}的全路径为{1}",path3,Path .GetFullPath (path3)); } 细节32重载一元。二元运算符 细节33对象也能排序 System.Array类提供的Sort()静态方法可以根据数字、字母顺序对数组中的项进行排序。 System.ICompareTo()接口指定了一种允许一个对象可基于某些特定键值进行排序的方法。该接口提供一个CompareTo()方法用于比较当前实例与同一类型的另一个对象。 返回值小于0表示当前实例小于另一个对象。 public class Student : IComparable { private int sid; public string name; public Student(int sid, string name) { this.sid = sid; this.name = name; } public int ID { get{return sid;} set { sid = value; } } int IComparable.CompareTo(object obj) { Student s = (Student)obj; if (this.sid > s.sid) { return 1; } if (this.sid < s.sid) { return -1; } else return 0; } } string str = string.Empty; Student []arr=new Student [4]; arr[0] = new Student(65,"张三"); arr[1] = new Student(62, "张三"); arr[2] = new Student(63, "张三"); arr[3] = new Student(63, "张三"); Array.Sort(arr);//对象排序 foreach (var item in arr) { } 细节34实现IDisposable接口清除对象 利用。net框架提供的方法处理非内存资源,也就是通过实现IDisposable接口来释放非托管的资源。 IDisposable接口:它的Dispose()方法用于执行与释放或重置非托管资源相关应用程序定义的任务。 为using语句提供的对象必须实现IDisposable接口,此接口提供了Dispose()方法,该方法释放资源。 public class Test : IDisposable { public Test() { Console.WriteLine("a"); } ~Test() { Console.WriteLine("b"); } public void Dispose() { Console.WriteLine("c"); } } static void Main(string[] args) { try { using (Test te = new Test()) { throw new Exception("safaf"); } } catch { } } 运行结果: a c b 细节35将字符串转成字符数组 。net框架在System.IO命名空间下的StringRead类可以实现把字符串转换为字符数组 StringRead类的Read()方法用于读取输入字符串中的字符快 public override int Read() { char[] buffer,//读取到的字符数组 int index,//表示从开始读取的位置 int count//要读取的字符数 } //将字符串转换为字符数组 protected void ZhuanHuan() { string str = "are you Read"; char[]c=new char[200]; StringReader sr = new StringReader(str); sr.Read(c,0,19); } 细节36将字符数组写入到字符串 StringBuider类和StringWriter类可以实现 public override int Read() { char[] buffer,//读取到的字符数组 int index,//表示从开始读取的位置 int count//要读取的字符数 } //将字符数组写入字符串 protected void Zhuan() { StringBuilder sb = new StringBuilder("One World"); char[] c = { '.','0','n','e','c','d',}; StringWriter sw = new StringWriter(sb); sw.Write(c,0,4); } 细节37使用var创建隐型局部变量 var关键字指示编译器能根据变量的初始化 表达式推断出变量的类型。 细节38Lambda表达式 构成:一个参数列表,Lambda操作符(=>),表达式()或语句块{} Lambda表达式有两种。Lambda操作符右边是表达式的叫做表达式Lambda,如果是一个大括号括起来的任意多条语句,那就是语句Lambda Lambda表达式赋值给委托类型必须满足一下条件: 1.Lambda表达式与委托类型的参数个数相同 2.Lambda表达式的每个参数都能被隐式的转化为委托类型的参数类型 3.Lambda表达式的返回值能够被隐式转化为委托类型的返回值类型。 delegate int AddOne(int i); delegate int ToAdd(int i,int j); delegate void Method(); delegate int Method1(); protected void Lambda() { AddOne addone; addone = x => x + 1; //隐式类型,表达式方式体 addone = x => { return x + 1; };//隐式类型,语句方法体 addone = (int x) => x + 1;//显示类型,表达式方式体 addone = (int x) => { return x + 1; };//显示语句方法体类型, ToAdd myto = (x, y) => x + y;//多个参数 Method method1 = () => { };//无参数,表达式方式体 Method1 method2 = () => 1;//无参数,语句方法体