C# 靜態(tài)變量與靜態(tài)方法實(shí)例研究
更新時(shí)間:2011年11月23日 21:13:36 作者:
寫(xiě)了一個(gè)翻譯英漢單詞辭典的小程序,發(fā)現(xiàn)在調(diào)用幾千次的時(shí)候速度很慢
程序如下:
public static string 英漢(string english,翻譯結(jié)果 一個(gè)或多個(gè))
{
string 英漢辭典 = Settings.Default.辭典所在目錄+"haou_dict.xml";
try
{
if (File.Exists(英漢辭典))
{
XDocument dictionary = XDocument.Load(英漢辭典);
var query = from p in dictionary.Descendants("Name")
where p.Value.ToLower() == english.ToLower()
select p.Parent.Element("Content");
if (query.FirstOrDefault() == null)
{
return null;
}
else//可以翻譯
{
if (一個(gè)或多個(gè)==翻譯結(jié)果.多個(gè))
{
return query.FirstOrDefault().Value.Trim();
}
else if (一個(gè)或多個(gè) == 翻譯結(jié)果.一個(gè))
{
return 得到第一個(gè)漢字詞(query.FirstOrDefault().Value);
}
throw new Exception("參數(shù)錯(cuò)誤!");
}
}
else
{
throw new Exception("詞典文件不存在!");
}
}
catch (Exception)
{
throw new Exception("詞典文件出錯(cuò)!");
}
}
分析了一下,原因在于每次調(diào)用這個(gè)方法時(shí)都會(huì)去載入黃條處這個(gè)英漢辭典,如果執(zhí)行2000次,就會(huì)載入2000次,自然速度慢,有沒(méi)有什么辦法在程序運(yùn)行時(shí)只載入一次呢?想起在尚學(xué)堂看過(guò)的設(shè)計(jì)模式中有一個(gè)單例工廠模式,使用了靜態(tài)變量,似乎能夠解決,實(shí)例驗(yàn)證:
先定義一個(gè)類:
class 翻譯{
public static XDocument 英漢辭典內(nèi)容 = 英漢辭典初始化();
public XDocument 構(gòu)造英漢辭典內(nèi)容;
public 翻譯()
{
構(gòu)造英漢辭典內(nèi)容 = 英漢辭典初始化();
}
public static XDocument 英漢辭典初始化()
{
if (File.Exists(英漢辭典文件))
{
return XDocument.Load(英漢辭典文件);
}
else
{
throw new Exception("英漢詞典文件不存在!");
}
}
}
主程序:
var one = 翻譯.英漢辭典內(nèi)容;
var two = 翻譯.英漢辭典內(nèi)容;
if (one==two)
{
MessageBox.Show("相同");
}
else
{
MessageBox.Show("不同");
}
one = new 翻譯().構(gòu)造英漢辭典內(nèi)容;
two = new 翻譯().構(gòu)造英漢辭典內(nèi)容;
if (one == two)
{
MessageBox.Show("相同");
}
else
{
MessageBox.Show("不同");
}
結(jié)果:
無(wú)論是使用靜態(tài)的翻譯.英漢辭典內(nèi)容,還是new 翻譯().構(gòu)造英漢辭典內(nèi)容,他們都調(diào)用了 英漢辭典初始化() ,但是靜態(tài)變量中的值只會(huì)初始化一次,后面每次訪問(wèn),都是上次處理過(guò)的值,所以第一次顯示的結(jié)果是相同,也就是說(shuō)one,two的值其實(shí)是一個(gè),第二個(gè)two訪問(wèn)的其實(shí)是第一次one初始化后的值;而使用類的構(gòu)造函數(shù)來(lái)初始化變量每次都會(huì)重復(fù)初始化,自然其結(jié)果不同.
再比如(以下內(nèi)容為轉(zhuǎn)載):
class Program
{
static void Main(string[] args)
{//輸出未經(jīng)定義的靜態(tài)變量,結(jié)果為0;也說(shuō)明了,在C#中未賦初值的變量系統(tǒng)自動(dòng)賦為0
Console.WriteLine(sort.i);
//靜態(tài)變量的訪問(wèn)方法(類名.靜態(tài)變量名),而且還可以在外部操作靜態(tài)變量呢,可見(jiàn)靜態(tài)變量并不神秘;
sort.i = 5;
//輸出5
Console.WriteLine(sort.i);
//還可以通過(guò)構(gòu)造函數(shù)對(duì)靜態(tài)變量初值呢,呵
sort sortTest = new sort();
//輸出構(gòu)造函數(shù)中的賦值 3;
Console.WriteLine(sort.i);
}
}
class sort
{
public static int i;
public sort()
{
i = 3;
}
}
總結(jié):在類內(nèi)部訪問(wèn)靜態(tài)變量時(shí),直接用靜態(tài)變量名即可,不用以(類名.靜態(tài)變量名),這樣的方式訪問(wèn),
除了有靜態(tài)變量之外,還有靜態(tài)類實(shí)例,還有靜態(tài)方法.但用法都是大同小異;
如:public static void myFun(){} //靜態(tài)方法
private static Random MyRandom=new Random(); //靜態(tài)類實(shí)例
之所以有時(shí)聲明為私有靜態(tài)變量,是為了讓它只初始化一次.這樣節(jié)省了內(nèi)存空間
但又想讓它在外部是不可訪問(wèn)的,這樣利用私有這個(gè)訪問(wèn)限定符就搞定了.
私有靜態(tài):安全又節(jié)省空間.
例:如果想在每次實(shí)例化類的時(shí)間生成一組隨機(jī)數(shù),但產(chǎn)生隨機(jī)數(shù)是要用到一個(gè)類的,即Random,這個(gè)類不是靜態(tài)類,它要產(chǎn)生實(shí)例,用產(chǎn)生的實(shí)例來(lái)生成隨機(jī)數(shù),但如果在每次類實(shí)例化時(shí)都產(chǎn)生一個(gè)Random實(shí)例,那內(nèi)存空間簡(jiǎn)直是極大的浪費(fèi),所以可以用:
private static Random MyRandom=new Random();
這樣每次類實(shí)例化時(shí),都會(huì)用同一個(gè)Random實(shí)例MyRandom來(lái)產(chǎn)生隨機(jī)數(shù)
復(fù)制代碼 代碼如下:
public static string 英漢(string english,翻譯結(jié)果 一個(gè)或多個(gè))
{
string 英漢辭典 = Settings.Default.辭典所在目錄+"haou_dict.xml";
try
{
if (File.Exists(英漢辭典))
{
XDocument dictionary = XDocument.Load(英漢辭典);
var query = from p in dictionary.Descendants("Name")
where p.Value.ToLower() == english.ToLower()
select p.Parent.Element("Content");
if (query.FirstOrDefault() == null)
{
return null;
}
else//可以翻譯
{
if (一個(gè)或多個(gè)==翻譯結(jié)果.多個(gè))
{
return query.FirstOrDefault().Value.Trim();
}
else if (一個(gè)或多個(gè) == 翻譯結(jié)果.一個(gè))
{
return 得到第一個(gè)漢字詞(query.FirstOrDefault().Value);
}
throw new Exception("參數(shù)錯(cuò)誤!");
}
}
else
{
throw new Exception("詞典文件不存在!");
}
}
catch (Exception)
{
throw new Exception("詞典文件出錯(cuò)!");
}
}
分析了一下,原因在于每次調(diào)用這個(gè)方法時(shí)都會(huì)去載入黃條處這個(gè)英漢辭典,如果執(zhí)行2000次,就會(huì)載入2000次,自然速度慢,有沒(méi)有什么辦法在程序運(yùn)行時(shí)只載入一次呢?想起在尚學(xué)堂看過(guò)的設(shè)計(jì)模式中有一個(gè)單例工廠模式,使用了靜態(tài)變量,似乎能夠解決,實(shí)例驗(yàn)證:
先定義一個(gè)類:
復(fù)制代碼 代碼如下:
class 翻譯{
public static XDocument 英漢辭典內(nèi)容 = 英漢辭典初始化();
public XDocument 構(gòu)造英漢辭典內(nèi)容;
public 翻譯()
{
構(gòu)造英漢辭典內(nèi)容 = 英漢辭典初始化();
}
public static XDocument 英漢辭典初始化()
{
if (File.Exists(英漢辭典文件))
{
return XDocument.Load(英漢辭典文件);
}
else
{
throw new Exception("英漢詞典文件不存在!");
}
}
}
主程序:
復(fù)制代碼 代碼如下:
var one = 翻譯.英漢辭典內(nèi)容;
var two = 翻譯.英漢辭典內(nèi)容;
if (one==two)
{
MessageBox.Show("相同");
}
else
{
MessageBox.Show("不同");
}
one = new 翻譯().構(gòu)造英漢辭典內(nèi)容;
two = new 翻譯().構(gòu)造英漢辭典內(nèi)容;
if (one == two)
{
MessageBox.Show("相同");
}
else
{
MessageBox.Show("不同");
}
結(jié)果:
分析如下:
無(wú)論是使用靜態(tài)的翻譯.英漢辭典內(nèi)容,還是new 翻譯().構(gòu)造英漢辭典內(nèi)容,他們都調(diào)用了 英漢辭典初始化() ,但是靜態(tài)變量中的值只會(huì)初始化一次,后面每次訪問(wèn),都是上次處理過(guò)的值,所以第一次顯示的結(jié)果是相同,也就是說(shuō)one,two的值其實(shí)是一個(gè),第二個(gè)two訪問(wèn)的其實(shí)是第一次one初始化后的值;而使用類的構(gòu)造函數(shù)來(lái)初始化變量每次都會(huì)重復(fù)初始化,自然其結(jié)果不同.
再比如(以下內(nèi)容為轉(zhuǎn)載):
復(fù)制代碼 代碼如下:
class Program
{
static void Main(string[] args)
{//輸出未經(jīng)定義的靜態(tài)變量,結(jié)果為0;也說(shuō)明了,在C#中未賦初值的變量系統(tǒng)自動(dòng)賦為0
Console.WriteLine(sort.i);
//靜態(tài)變量的訪問(wèn)方法(類名.靜態(tài)變量名),而且還可以在外部操作靜態(tài)變量呢,可見(jiàn)靜態(tài)變量并不神秘;
sort.i = 5;
//輸出5
Console.WriteLine(sort.i);
//還可以通過(guò)構(gòu)造函數(shù)對(duì)靜態(tài)變量初值呢,呵
sort sortTest = new sort();
//輸出構(gòu)造函數(shù)中的賦值 3;
Console.WriteLine(sort.i);
}
}
class sort
{
public static int i;
public sort()
{
i = 3;
}
}
總結(jié):在類內(nèi)部訪問(wèn)靜態(tài)變量時(shí),直接用靜態(tài)變量名即可,不用以(類名.靜態(tài)變量名),這樣的方式訪問(wèn),
除了有靜態(tài)變量之外,還有靜態(tài)類實(shí)例,還有靜態(tài)方法.但用法都是大同小異;
如:public static void myFun(){} //靜態(tài)方法
private static Random MyRandom=new Random(); //靜態(tài)類實(shí)例
之所以有時(shí)聲明為私有靜態(tài)變量,是為了讓它只初始化一次.這樣節(jié)省了內(nèi)存空間
但又想讓它在外部是不可訪問(wèn)的,這樣利用私有這個(gè)訪問(wèn)限定符就搞定了.
私有靜態(tài):安全又節(jié)省空間.
例:如果想在每次實(shí)例化類的時(shí)間生成一組隨機(jī)數(shù),但產(chǎn)生隨機(jī)數(shù)是要用到一個(gè)類的,即Random,這個(gè)類不是靜態(tài)類,它要產(chǎn)生實(shí)例,用產(chǎn)生的實(shí)例來(lái)生成隨機(jī)數(shù),但如果在每次類實(shí)例化時(shí)都產(chǎn)生一個(gè)Random實(shí)例,那內(nèi)存空間簡(jiǎn)直是極大的浪費(fèi),所以可以用:
private static Random MyRandom=new Random();
這樣每次類實(shí)例化時(shí),都會(huì)用同一個(gè)Random實(shí)例MyRandom來(lái)產(chǎn)生隨機(jī)數(shù)
相關(guān)文章
c# winform窗口一直置頂顯示在桌面最上方或最底層的方法
winform窗口一直置頂顯示在桌面最上方,這樣的功能真的很實(shí)用的,很多的軟件窗口都有這樣的功能,本文也來(lái)實(shí)現(xiàn)一個(gè),感興趣的你千萬(wàn)不要錯(cuò)過(guò)了,希望本文對(duì)你有所幫助2013-01-01C#?winform跨線程操作控件的實(shí)現(xiàn)
本文主要介紹了C#?winform跨線程操作控件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06深入C# winform清除由GDI繪制出來(lái)的所有線條或圖形的解決方法
本篇文章是對(duì)在C#中使用winform清除由GDI繪制出來(lái)的所有線條或圖形的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C#將Sql數(shù)據(jù)保存到Excel文件中的方法
這篇文章主要介紹了C#將Sql數(shù)據(jù)保存到Excel文件中的方法,文中的ExportExcel可起到將sql數(shù)據(jù)導(dǎo)出為Excel的作用,需要的朋友可以參考下2014-08-08C#關(guān)于System.Collections空間詳解
這篇文章主要介紹了C#關(guān)于System.Collections空間,需要的朋友可以參考下2014-07-07在Winform程序中使用Spire.Pdf實(shí)現(xiàn)頁(yè)面添加印章功能的實(shí)現(xiàn)
這篇文章主要介紹了在Winform程序中使用Spire.Pdf實(shí)現(xiàn)頁(yè)面添加印章功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09