Net高级技术——IDisposable
IDisposable概述
GC(垃圾收集器)只能回收托管(Managed)内存资源,对于数据库连接、文件句柄、Socket连接等这些资源(非托管资源,UnManaged)就无能为例,必须程序员自己控制资源的回收。非托管资源:SqlConnection、FileStream等。
对于使用非内存资源的类,完全可以自己定义一个销毁资源的方法来供程序员回收,.net推荐实现IDisposable接口(为了规范非托管资源的回收),在Dispose方法中进行回收。
实现了IDisposable接口的对象都可以使用using进行资源管理。using就是帮我们做了:
复制代码
1FileStreamfs=newF.....
2try{
3fs.read()....
4}
5finally{
6fs.Dispose();
7}
复制代码
实现了IDisposable接口的对象都要进行回收,否则很可能有内存泄露。
非托管内存资源才需要实现IDisposable
IDisposable例子
复制代码
1namespace资源回收
2{
3classProgram
4{
5staticvoidMain(string[]args)
6{
7//使用using对实现IDisposable的类了进行资源管理
8/拿到一个对象的时候,首先判断这个对象是否实现了IDisposable接口,如果实现了,最好就用using包裹住这个对象,保证这个对象用完之后被释放掉,否则很可能出现资源泄露的问题
9/
10using(Telphonet1=newTelphone())
11{
12t1.Open();
13t1.Speak("hello");
14t1.Bomb();
15//t1.Dispose();//如果在这里调用了Dispose()方法释放资源,那么在执行t1.Open()方法就出错,电话线已经被剪断了,无法再打电话了
16t1.Open();
17t1.Speak("Iamback!");
18}//代码执行到这里后,就会调用Dispose方法来进行资源回收
19Console.ReadKey();
20}
21}
22///
23///Telphone类实现了IDisposable接口
24///
25classTelphone:IDisposable
26{
27///
28///电话状态
29///
30privateTelphoneStatestate;
31///
32///打电话
33///
34publicvoidOpen()
35{
36if(state==TelphoneState.Disposed)
37{
38thrownewException("电话线已经被剪断,无法打开!");
39}
40state=TelphoneState.Open;
41Console.WriteLine("拿起电话");
42}
43///
44///说话
45///
46///说话内容
47publicvoidSpeak(strings)
48{
49if(state!=TelphoneState.Open)
50{
51thrownewException("没有连接");
52}
53Console.WriteLine(s);
54}
55///
56///挂掉电话
57///
58publicvoidBomb()
59{
60state=TelphoneState.Close;
61Console.WriteLine("挂掉电话");
62}
63#regionIDisposable成员
64///
65///实现IDisposable接口中的Dispose()方法来释放非托管资源
66///如何释放非托管资源由程序自己定
67///
68publicvoidDispose()
69{
70if(state==TelphoneState.Open)
71{
72Bomb();//挂掉电话
73}
74state=TelphoneState.Disposed;
75Console.WriteLine("剪断电话线");
76}
77#endregion
78}
79///
80///电话状态枚举
81///
82enumTelphoneState
83{
84Open,Close,Disposed
85}
86}
.Net高级技术——结构体
结构体
结构体和类的区别:结构体是值类型,类是引用类型
结构体非常类似于类,但是值类型(拷贝传递),不能被继承
Int32、DateTime等都是结构体,从ValueType继承,值类型。
结构体测试程序:
复制代码
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Linq;
4usingSystem.Text;
5usingSystem.Drawing;
6namespace结构体
7{
8classProgram
9{
10staticvoidMain(string[]args)
11{
12Personp1=newPerson();
13Personp2=p1;
14p1.Age=24;
15p1.Name="孤傲苍狼";
16Console.WriteLine("p1.Name={0},p1.Age={1}",p1.Name,p1.Age);
17Console.WriteLine("p2.Name={0},p2.Age={1}",p2.Name,p2.Age);
18p2.Name="白虎神皇";
19Console.WriteLine("p1.Name={0},p1.Age={1}",p1.Name,p1.Age);
20Console.WriteLine("p2.Name={0},p2.Age={1}",p2.Name,p2.Age);
21Console.WriteLine(object.ReferenceEquals(p1,p2));
22Console.WriteLine(object.Equals(p1,p2));
23Console.WriteLine(www.wang027.com.(p1==p2);
24MyPointpoint1=ReadKeynewMyPoint();
25MyPointpoint2=point1;
26Console.WriteLine(object.ReferenceEquals(point1,point2));//结构体是值类型,拷贝一份,因此point1和point2是两个不同的对象
27point1.X=10;
28point1.Y=20;
29point1.SayHello();
30Console.WriteLine("point1.X={0},point1.Y={1}",point1.X,point1.Y);
31Console.WriteLine("point2.X={0},point2.Y={1}",point2.X,point2.Y);
32Console.ReadKey();
33}
34}
35//结构体非常类似于类,但是值类型(拷贝传递),不能被继承
36//Int32、DateTime等都是结构体,从ValueType继承,值类型。
37///
38///定义结构体
39///
40structMyPoint
41{
42///
43///定义结构体的属性
44///
45publicintX{get;set;}
46///
47///定义结构体的属性
48///
49publicintY{get;set;}
50///
51///定义结构体的方法
52///
53publicvoidSayHello()
54{
55Console.WriteLine("HelloWorld!");
56}
57}
58///
59///定义类
60///
61classPerson
62{
63publicintAge{get;set;}
64publicstringName{get;set;}
65}
66}
Stopwatch的使用
复制代码
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Linq;
4usingSystem.Text;
5usingSystem.Threading.Tasks;
6
7namespaceStopwatch的使用
8{
9classProgram
10{
11
12///
13///使用Stopwatch比较for循环和foreach循环的效率
14///
15///
16staticvoidMain(string[]args)
17{
18
19int[]intArr=newint[1000000];
20for(inti=1;i<=1000000;i++)
21{
22intArr[i-1]=i;
23}
24
25//使用Stopwatch统计程序运行的时间
26/
27Stopwatch提供了几个方法用以控制Stopwatch对象。
28Start方法开始一个计时操作,Stop方法停止计时。
29此时如果第二次使用Start方法,将继续计时,最终的计时结果为两次计时的累加。
30为避免这种情况,在第二次计时前用Reset方法将对象归零。这三个方法都不需要参数
31/
32System.Diagnostics.Stopwatchsw=newSystem.Diagnostics.Stopwatch();
33sw.Start();//开始计时
34
35intsum=0;
36
37for(inti=1;i<=intArr.Length;i++)
38{
39sum+=i;
40}
41Console.WriteLine("sum={0}",sum);
42
43sw.Stop();//停止计时
44longresult=sw.ElapsedMilliseconds;//获得程序运行的时间
45Console.WriteLine("使用for循环计算从1加到1000000的和所需要的时间是:{0}",result);
46
47Console.WriteLine("");
48sw.Reset();
49sw.Start();
50
51sum=0;
52foreach(variteminintArr)
53{
54sum+=item;
55}
56Console.WriteLine("sum={0}",sum);
57Console.WriteLine("使用foreach循环计算从1加到1000000的和所需要的时间是:{0}",sw.ElapsedMilliseconds);
58sw.Stop();
59
60Console.ReadKey();
61}
62}
63}
|
|