C#基礎(chǔ)概念二十五問(wèn) 16-20
更新時(shí)間:2007年04月09日 00:00:00 作者:
16.類和結(jié)構(gòu)的區(qū)別?
答:
類:
類是引用類型在堆上分配,類的實(shí)例進(jìn)行賦值只是復(fù)制了引用,都指向同一段實(shí)際對(duì)象分配的內(nèi)存
類有構(gòu)造和析構(gòu)函數(shù)
類可以繼承和被繼承
結(jié)構(gòu):
結(jié)構(gòu)是值類型在棧上分配(雖然棧的訪問(wèn)速度比較堆要快,但棧的資源有限放),結(jié)構(gòu)的賦值將分配產(chǎn)生一個(gè)新的對(duì)象。
結(jié)構(gòu)沒(méi)有構(gòu)造函數(shù),但可以添加。結(jié)構(gòu)沒(méi)有析構(gòu)函數(shù)
結(jié)構(gòu)不可以繼承自另一個(gè)結(jié)構(gòu)或被繼承,但和類一樣可以繼承自接口
示例:
根據(jù)以上比較,我們可以得出一些輕量級(jí)的對(duì)象最好使用結(jié)構(gòu),但數(shù)據(jù)量大或有復(fù)雜處理邏輯對(duì)象最好使用類。
如:Geoemtry(GIS 里的一個(gè)概論,在 OGC 標(biāo)準(zhǔn)里有定義) 最好使用類,而 Geometry 中點(diǎn)的成員最好使用結(jié)構(gòu)
using System;
using System.Collections.Generic;
using System.Text;
namespace Example16
{
interface IPoint
{
double X
{
get;
set;
}
double Y
{
get;
set;
}
double Z
{
get;
set;
}
}
//結(jié)構(gòu)也可以從接口繼承
struct Point: IPoint
{
private double x, y, z;
//結(jié)構(gòu)也可以增加構(gòu)造函數(shù)
public Point(double X, double Y, double Z)
{
this.x = X;
this.y = Y;
this.z = Z;
}
public double X
{
get { return x; }
set { x = value; }
}
public double Y
{
get { return x; }
set { x = value; }
}
public double Z
{
get { return x; }
set { x = value; }
}
}
//在此簡(jiǎn)化了點(diǎn)狀Geometry的設(shè)計(jì),實(shí)際產(chǎn)品中還包含Project(坐標(biāo)變換)等復(fù)雜操作
class PointGeometry
{
private Point value;
public PointGeometry(double X, double Y, double Z)
{
value = new Point(X, Y, Z);
}
public PointGeometry(Point value)
{
//結(jié)構(gòu)的賦值將分配新的內(nèi)存
this.value = value;
}
public double X
{
get { return value.X; }
set { this.value.X = value; }
}
public double Y
{
get { return value.Y; }
set { this.value.Y = value; }
}
public double Z
{
get { return value.Z; }
set { this.value.Z = value; }
}
public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
{
return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
}
public override string ToString()
{
return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
}
}
class Program
{
static void Main(string[] args)
{
Point tmpPoint = new Point(1, 2, 3);
PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
tmpPG2.X = 4;
tmpPG2.Y = 5;
tmpPG2.Z = 6;
//由于結(jié)構(gòu)是值類型,tmpPG1 和 tmpPG2 的坐標(biāo)并不一樣
Console.WriteLine(tmpPG1);
Console.WriteLine(tmpPG2);
//由于類是引用類型,對(duì)tmpPG1坐標(biāo)修改后影響到了tmpPG3
PointGeometry tmpPG3 = tmpPG1;
tmpPG1.X = 7;
tmpPG1.Y = 8;
tmpPG1.Z = 9;
Console.WriteLine(tmpPG1);
Console.WriteLine(tmpPG3);
Console.ReadLine();
}
}
}
結(jié)果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9
17.接口的多繼承會(huì)帶來(lái)哪些問(wèn)題?
答:
C# 中的接口與類不同,可以使用多繼承,即一個(gè)子接口可以有多個(gè)父接口。但如果兩個(gè)父成員具有同名的成員,就產(chǎn)生了二義性(這也正是 C# 中類取消了多繼承的原因之一),這時(shí)在實(shí)現(xiàn)時(shí)最好使用顯式的聲明
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example17
{
class Program
{
//一個(gè)完整的接口聲明示例
interface IExample
{
//屬性
string P
{
get;
set;
}
//方法
string F(int Value);
//事件
event EventHandler E;
//索引指示器
string this[int Index]
{
get;
set;
}
}
interface IA
{
int Count { get; set;}
}
interface IB
{
int Count();
}
//IC接口從IA和IB多重繼承
interface IC : IA, IB
{
}
class C : IC
{
private int count = 100;
//顯式聲明實(shí)現(xiàn)IA接口中的Count屬性
int IA.Count
{
get { return 100; }
set { count = value; }
}
//顯式聲明實(shí)現(xiàn)IB接口中的Count方法
int IB.Count()
{
return count * count;
}
}
static void Main(string[] args)
{
C tmpObj = new C();
//調(diào)用時(shí)也要顯式轉(zhuǎn)換
Console.WriteLine("Count property: {0}", ((IA)tmpObj).Count);
Console.WriteLine("Count function: {0}", ((IB)tmpObj).Count());
Console.ReadLine();
}
}
}
結(jié)果:
Count property: 100
Count function: 10000
18.抽象類和接口的區(qū)別?
答:
抽象類(abstract class)可以包含功能定義和實(shí)現(xiàn),接口(interface)只能包含功能定義
抽象類是從一系列相關(guān)對(duì)象中抽象出來(lái)的概念, 因此反映的是事物的內(nèi)部共性;接口是為了滿足外部調(diào)用而定義的一個(gè)功能約定, 因此反映的是事物的外部特性
分析對(duì)象,提煉內(nèi)部共性形成抽象類,用以表示對(duì)象本質(zhì),即“是什么”
為外部提供調(diào)用或功能需要擴(kuò)充時(shí)優(yōu)先使用接口
19.別名指示符是什么?
答:
通過(guò)別名指示符我們可以為某個(gè)類型起一個(gè)別名
主要用于解決兩個(gè)命名空間內(nèi)有同名類型的沖突或避免使用冗余的命名空間
別名指示符在所有命名空間最外層定義,作用域?yàn)檎麄€(gè)單元文件。如果定義在某個(gè)命名空間內(nèi),那么它只在直接隸屬的命名空間內(nèi)起作用
示例:
Class1.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01
{
class Class1
{
public override string ToString()
{
return "com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1";
}
}
}
Class2.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02
{
class Class1
{
public override string ToString()
{
return "com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02's Class1";
}
}
}
主單元(Program.cs):
using System;
using System.Collections.Generic;
using System.Text;
//使用別名指示符解決同名類型的沖突
//在所有命名空間最外層定義,作用域?yàn)檎麄€(gè)單元文件
using Lib01Class1 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
using Lib02Class2 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02.Class1;
namespace Example19
{
namespace Test1
{
//Test1Class1在Test1命名空間內(nèi)定義,作用域僅在Test1之內(nèi)
using Test1Class1 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
class Class1
{
//Lib01Class1和Lib02Class2在這可以正常使用
Lib01Class1 tmpObj1 = new Lib01Class1();
Lib02Class2 tmpObj2 = new Lib02Class2();
//TestClass1在這可以正常使用
Test1Class1 tmpObj3 = new Test1Class1();
}
}
namespace Test2
{
using Test1Class2 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
class Program
{
static void Main(string[] args)
{
//Lib01Class1和Lib02Class2在這可以正常使用
Lib01Class1 tmpObj1 = new Lib01Class1();
Lib02Class2 tmpObj2 = new Lib02Class2();
//注意這里,TestClass1在這不可以正常使用。
//因?yàn)?,在Test2命名空間內(nèi)不能使用Test1命名空間定義的別名
//Test1Class1 tmpObj3 = new Test1Class1();
//TestClass2在這可以正常使用
Test1Class2 tmpObj3 = new Test1Class2();
Console.WriteLine(tmpObj1);
Console.WriteLine(tmpObj2);
Console.WriteLine(tmpObj3);
Console.ReadLine();
}
}
}
}
結(jié)果:
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02's Class1
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1
20.如何手工釋放資源?
答:
.NET 平臺(tái)在內(nèi)存管理方面提供了GC(Garbage Collection),負(fù)責(zé)自動(dòng)釋放托管資源和內(nèi)存回收的工作。但在以下兩種情況需要我們手工進(jìn)行資源釋放:一、由于它無(wú)法對(duì)非托管資源進(jìn)行釋放,所以我們必須自己提供方法來(lái)釋放對(duì)象內(nèi)分配的非托管資源,比如你在對(duì)象的實(shí)現(xiàn)代碼中使用了一個(gè)COM對(duì)象;二、你的類在運(yùn)行是會(huì)產(chǎn)生大量實(shí)例(象 GIS 中的Geometry),必須自己手工釋放這些資源以提高程序的運(yùn)行效率
最理想的辦法是通過(guò)實(shí)現(xiàn)一個(gè)接口顯式的提供給客戶調(diào)用端手工釋放對(duì)象,System 命名空間內(nèi)有一個(gè) IDisposable 接口,拿來(lái)做這事非常合適,省得我們自己再聲明一個(gè)接口了
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example20
{
class Program
{
class Class1 : IDisposable
{
//析構(gòu)函數(shù),編譯后變成 protected void Finalize(),GC會(huì)在回收對(duì)象前會(huì)調(diào)用調(diào)用該方法
~Class1()
{
Dispose(false);
}
//通過(guò)實(shí)現(xiàn)該接口,客戶可以顯式地釋放對(duì)象,而不需要等待GC來(lái)釋放資源,據(jù)說(shuō)那樣會(huì)降低效率
void IDisposable.Dispose()
{
Dispose(true);
}
//將釋放非托管資源設(shè)計(jì)成一個(gè)虛函數(shù),提供在繼承類中釋放基類的資源的能力
protected virtual void ReleaseUnmanageResources()
{
//Do something...
}
//私有函數(shù)用以釋放非托管資源
private void Dispose(bool disposing)
{
ReleaseUnmanageResources();
//為true時(shí)表示是客戶顯式調(diào)用了釋放函數(shù),需通知GC不要再調(diào)用對(duì)象的Finalize方法
//為false時(shí)肯定是GC調(diào)用了對(duì)象的Finalize方法,所以沒(méi)有必要再告訴GC你不要調(diào)用我的Finalize方法啦
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
static void Main(string[] args)
{
//tmpObj1沒(méi)有手工釋放資源,就等著GC來(lái)慢慢的釋放它吧
Class1 tmpObj1 = new Class1();
//tmpObj2調(diào)用了Dispose方法,傳說(shuō)比等著GC來(lái)釋放它效率要調(diào)一些
//個(gè)人認(rèn)為是因?yàn)橐饌€(gè)對(duì)象的查看其元數(shù)據(jù),以確認(rèn)是否實(shí)現(xiàn)了Dispose方法吧
//當(dāng)然最重要的是我們可以自己確定釋放的時(shí)間以節(jié)省內(nèi)存,優(yōu)化程序運(yùn)行效率
Class1 tmpObj2 = new Class1();
((IDisposable)tmpObj2).Dispose();
}
}
}
答:
類:
類是引用類型在堆上分配,類的實(shí)例進(jìn)行賦值只是復(fù)制了引用,都指向同一段實(shí)際對(duì)象分配的內(nèi)存
類有構(gòu)造和析構(gòu)函數(shù)
類可以繼承和被繼承
結(jié)構(gòu):
結(jié)構(gòu)是值類型在棧上分配(雖然棧的訪問(wèn)速度比較堆要快,但棧的資源有限放),結(jié)構(gòu)的賦值將分配產(chǎn)生一個(gè)新的對(duì)象。
結(jié)構(gòu)沒(méi)有構(gòu)造函數(shù),但可以添加。結(jié)構(gòu)沒(méi)有析構(gòu)函數(shù)
結(jié)構(gòu)不可以繼承自另一個(gè)結(jié)構(gòu)或被繼承,但和類一樣可以繼承自接口
示例:
根據(jù)以上比較,我們可以得出一些輕量級(jí)的對(duì)象最好使用結(jié)構(gòu),但數(shù)據(jù)量大或有復(fù)雜處理邏輯對(duì)象最好使用類。
如:Geoemtry(GIS 里的一個(gè)概論,在 OGC 標(biāo)準(zhǔn)里有定義) 最好使用類,而 Geometry 中點(diǎn)的成員最好使用結(jié)構(gòu)
using System;
using System.Collections.Generic;
using System.Text;
namespace Example16
{
interface IPoint
{
double X
{
get;
set;
}
double Y
{
get;
set;
}
double Z
{
get;
set;
}
}
//結(jié)構(gòu)也可以從接口繼承
struct Point: IPoint
{
private double x, y, z;
//結(jié)構(gòu)也可以增加構(gòu)造函數(shù)
public Point(double X, double Y, double Z)
{
this.x = X;
this.y = Y;
this.z = Z;
}
public double X
{
get { return x; }
set { x = value; }
}
public double Y
{
get { return x; }
set { x = value; }
}
public double Z
{
get { return x; }
set { x = value; }
}
}
//在此簡(jiǎn)化了點(diǎn)狀Geometry的設(shè)計(jì),實(shí)際產(chǎn)品中還包含Project(坐標(biāo)變換)等復(fù)雜操作
class PointGeometry
{
private Point value;
public PointGeometry(double X, double Y, double Z)
{
value = new Point(X, Y, Z);
}
public PointGeometry(Point value)
{
//結(jié)構(gòu)的賦值將分配新的內(nèi)存
this.value = value;
}
public double X
{
get { return value.X; }
set { this.value.X = value; }
}
public double Y
{
get { return value.Y; }
set { this.value.Y = value; }
}
public double Z
{
get { return value.Z; }
set { this.value.Z = value; }
}
public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
{
return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
}
public override string ToString()
{
return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
}
}
class Program
{
static void Main(string[] args)
{
Point tmpPoint = new Point(1, 2, 3);
PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
tmpPG2.X = 4;
tmpPG2.Y = 5;
tmpPG2.Z = 6;
//由于結(jié)構(gòu)是值類型,tmpPG1 和 tmpPG2 的坐標(biāo)并不一樣
Console.WriteLine(tmpPG1);
Console.WriteLine(tmpPG2);
//由于類是引用類型,對(duì)tmpPG1坐標(biāo)修改后影響到了tmpPG3
PointGeometry tmpPG3 = tmpPG1;
tmpPG1.X = 7;
tmpPG1.Y = 8;
tmpPG1.Z = 9;
Console.WriteLine(tmpPG1);
Console.WriteLine(tmpPG3);
Console.ReadLine();
}
}
}
結(jié)果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9
17.接口的多繼承會(huì)帶來(lái)哪些問(wèn)題?
答:
C# 中的接口與類不同,可以使用多繼承,即一個(gè)子接口可以有多個(gè)父接口。但如果兩個(gè)父成員具有同名的成員,就產(chǎn)生了二義性(這也正是 C# 中類取消了多繼承的原因之一),這時(shí)在實(shí)現(xiàn)時(shí)最好使用顯式的聲明
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example17
{
class Program
{
//一個(gè)完整的接口聲明示例
interface IExample
{
//屬性
string P
{
get;
set;
}
//方法
string F(int Value);
//事件
event EventHandler E;
//索引指示器
string this[int Index]
{
get;
set;
}
}
interface IA
{
int Count { get; set;}
}
interface IB
{
int Count();
}
//IC接口從IA和IB多重繼承
interface IC : IA, IB
{
}
class C : IC
{
private int count = 100;
//顯式聲明實(shí)現(xiàn)IA接口中的Count屬性
int IA.Count
{
get { return 100; }
set { count = value; }
}
//顯式聲明實(shí)現(xiàn)IB接口中的Count方法
int IB.Count()
{
return count * count;
}
}
static void Main(string[] args)
{
C tmpObj = new C();
//調(diào)用時(shí)也要顯式轉(zhuǎn)換
Console.WriteLine("Count property: {0}", ((IA)tmpObj).Count);
Console.WriteLine("Count function: {0}", ((IB)tmpObj).Count());
Console.ReadLine();
}
}
}
結(jié)果:
Count property: 100
Count function: 10000
18.抽象類和接口的區(qū)別?
答:
抽象類(abstract class)可以包含功能定義和實(shí)現(xiàn),接口(interface)只能包含功能定義
抽象類是從一系列相關(guān)對(duì)象中抽象出來(lái)的概念, 因此反映的是事物的內(nèi)部共性;接口是為了滿足外部調(diào)用而定義的一個(gè)功能約定, 因此反映的是事物的外部特性
分析對(duì)象,提煉內(nèi)部共性形成抽象類,用以表示對(duì)象本質(zhì),即“是什么”
為外部提供調(diào)用或功能需要擴(kuò)充時(shí)優(yōu)先使用接口
19.別名指示符是什么?
答:
通過(guò)別名指示符我們可以為某個(gè)類型起一個(gè)別名
主要用于解決兩個(gè)命名空間內(nèi)有同名類型的沖突或避免使用冗余的命名空間
別名指示符在所有命名空間最外層定義,作用域?yàn)檎麄€(gè)單元文件。如果定義在某個(gè)命名空間內(nèi),那么它只在直接隸屬的命名空間內(nèi)起作用
示例:
Class1.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01
{
class Class1
{
public override string ToString()
{
return "com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1";
}
}
}
Class2.cs:
using System;
using System.Collections.Generic;
using System.Text;
namespace com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02
{
class Class1
{
public override string ToString()
{
return "com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02's Class1";
}
}
}
主單元(Program.cs):
using System;
using System.Collections.Generic;
using System.Text;
//使用別名指示符解決同名類型的沖突
//在所有命名空間最外層定義,作用域?yàn)檎麄€(gè)單元文件
using Lib01Class1 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
using Lib02Class2 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02.Class1;
namespace Example19
{
namespace Test1
{
//Test1Class1在Test1命名空間內(nèi)定義,作用域僅在Test1之內(nèi)
using Test1Class1 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
class Class1
{
//Lib01Class1和Lib02Class2在這可以正常使用
Lib01Class1 tmpObj1 = new Lib01Class1();
Lib02Class2 tmpObj2 = new Lib02Class2();
//TestClass1在這可以正常使用
Test1Class1 tmpObj3 = new Test1Class1();
}
}
namespace Test2
{
using Test1Class2 = com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01.Class1;
class Program
{
static void Main(string[] args)
{
//Lib01Class1和Lib02Class2在這可以正常使用
Lib01Class1 tmpObj1 = new Lib01Class1();
Lib02Class2 tmpObj2 = new Lib02Class2();
//注意這里,TestClass1在這不可以正常使用。
//因?yàn)?,在Test2命名空間內(nèi)不能使用Test1命名空間定義的別名
//Test1Class1 tmpObj3 = new Test1Class1();
//TestClass2在這可以正常使用
Test1Class2 tmpObj3 = new Test1Class2();
Console.WriteLine(tmpObj1);
Console.WriteLine(tmpObj2);
Console.WriteLine(tmpObj3);
Console.ReadLine();
}
}
}
}
結(jié)果:
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib02's Class1
com.nblogs.reonlyrun.CSharp25QExample.Example19.Lib01's Class1
20.如何手工釋放資源?
答:
.NET 平臺(tái)在內(nèi)存管理方面提供了GC(Garbage Collection),負(fù)責(zé)自動(dòng)釋放托管資源和內(nèi)存回收的工作。但在以下兩種情況需要我們手工進(jìn)行資源釋放:一、由于它無(wú)法對(duì)非托管資源進(jìn)行釋放,所以我們必須自己提供方法來(lái)釋放對(duì)象內(nèi)分配的非托管資源,比如你在對(duì)象的實(shí)現(xiàn)代碼中使用了一個(gè)COM對(duì)象;二、你的類在運(yùn)行是會(huì)產(chǎn)生大量實(shí)例(象 GIS 中的Geometry),必須自己手工釋放這些資源以提高程序的運(yùn)行效率
最理想的辦法是通過(guò)實(shí)現(xiàn)一個(gè)接口顯式的提供給客戶調(diào)用端手工釋放對(duì)象,System 命名空間內(nèi)有一個(gè) IDisposable 接口,拿來(lái)做這事非常合適,省得我們自己再聲明一個(gè)接口了
示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace Example20
{
class Program
{
class Class1 : IDisposable
{
//析構(gòu)函數(shù),編譯后變成 protected void Finalize(),GC會(huì)在回收對(duì)象前會(huì)調(diào)用調(diào)用該方法
~Class1()
{
Dispose(false);
}
//通過(guò)實(shí)現(xiàn)該接口,客戶可以顯式地釋放對(duì)象,而不需要等待GC來(lái)釋放資源,據(jù)說(shuō)那樣會(huì)降低效率
void IDisposable.Dispose()
{
Dispose(true);
}
//將釋放非托管資源設(shè)計(jì)成一個(gè)虛函數(shù),提供在繼承類中釋放基類的資源的能力
protected virtual void ReleaseUnmanageResources()
{
//Do something...
}
//私有函數(shù)用以釋放非托管資源
private void Dispose(bool disposing)
{
ReleaseUnmanageResources();
//為true時(shí)表示是客戶顯式調(diào)用了釋放函數(shù),需通知GC不要再調(diào)用對(duì)象的Finalize方法
//為false時(shí)肯定是GC調(diào)用了對(duì)象的Finalize方法,所以沒(méi)有必要再告訴GC你不要調(diào)用我的Finalize方法啦
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
static void Main(string[] args)
{
//tmpObj1沒(méi)有手工釋放資源,就等著GC來(lái)慢慢的釋放它吧
Class1 tmpObj1 = new Class1();
//tmpObj2調(diào)用了Dispose方法,傳說(shuō)比等著GC來(lái)釋放它效率要調(diào)一些
//個(gè)人認(rèn)為是因?yàn)橐饌€(gè)對(duì)象的查看其元數(shù)據(jù),以確認(rèn)是否實(shí)現(xiàn)了Dispose方法吧
//當(dāng)然最重要的是我們可以自己確定釋放的時(shí)間以節(jié)省內(nèi)存,優(yōu)化程序運(yùn)行效率
Class1 tmpObj2 = new Class1();
((IDisposable)tmpObj2).Dispose();
}
}
}
相關(guān)文章
C#實(shí)現(xiàn)為一張大尺寸圖片創(chuàng)建縮略圖的方法
這篇文章主要介紹了C#實(shí)現(xiàn)為一張大尺寸圖片創(chuàng)建縮略圖的方法,涉及C#創(chuàng)建縮略圖的相關(guān)圖片操作技巧,需要的朋友可以參考下2015-06-06c#使用微信接口開(kāi)發(fā)微信門(mén)戶應(yīng)用
本系列文章希望從一個(gè)循序漸進(jìn)的角度上,全面介紹微信的相關(guān)開(kāi)發(fā)過(guò)程和相關(guān)經(jīng)驗(yàn)總結(jié),希望給大家了解一下相關(guān)的開(kāi)發(fā)歷程。2014-03-03Unity3D實(shí)現(xiàn)待機(jī)狀態(tài)圖片循環(huán)淡入淡出
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)待機(jī)狀態(tài)圖片循環(huán)淡入淡出,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C#公眾號(hào)開(kāi)發(fā)之給用戶發(fā)紅包
這篇文章主要為大家詳細(xì)介紹了C#公眾號(hào)開(kāi)發(fā)之給用戶發(fā)紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08C#判斷指定驅(qū)動(dòng)器是否是Fat分區(qū)格式的方法
這篇文章主要介紹了C#判斷指定驅(qū)動(dòng)器是否是Fat分區(qū)格式的方法,涉及C#中DriveFormat屬性的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04