| 導購 | 订阅 | 在线投稿
分享
 
 
 

《Effective C#》Item 8:確保「0」在值類型中是有效的

來源:互聯網  2007-09-22 05:02:29  評論

大家在看了這標題後,肯定會覺的,爲什麽要確保“0”是有效的,這一點主要是跟值類型的內存分配有關,值類型有默認的構造函數,這是沒法避免的,因此值類型變量中的成員在初始化的時候所出現的細微問題(對于值類型這方面的知識可以參看我前面一篇文章)。

http://blog.csdn.net/Knight94/archive/2006/07/01/861383.aspx

日常中比較常見的兩種值類型,一個是enum定義的枚舉類型,一個是用struct定義的數據類型。那我接下來就分別說明這兩種類型如果不定義“0”爲一個有效值的所能造成的後果,再分別說明如何加以修改來彌補這類錯誤。

對于enum定義的枚舉類型來說,默認的起始值爲0,但是如果在定義的時候,按照如下的方式去定義的話,有時候會造成意想不到的錯誤。

public enum ERROR_CODE

{

INVALID_FILE_NAME = 1001,

CANT_BE_ACCESS = 1002,

}

如上的定義是沒有默認值0的,那麽當我顯示的去定義一個此類型變量,例如:

ERROR_CODE myError = new ERROR_CODE();

Debug.WriteLine( string.Format( "{0}", (int)myError ) );

可以看出如上的輸出結果是0,但是它不是一個有效的值,也許這種錯誤可能很少出現,但是在struct複合類型中這種錯誤表現得更爲明顯。例如:

public struct ErrorMsg

{

private ERROR_CODE err;

private string strMsg;

// other properties or methods here

}

對于如上的結構類型來說,由于默認構造函數存在,所以當創建一個ErrorMsg變量的時候,那麽對于err這個成員的值是無效的。有人可能會說,增加構造函數來限制等等的做法來避免這類錯誤。那麽爲什麽與其在ErrorMsg中增加限制,不如在定義ERROR_CODE的時候就避免呢。其實這類錯誤的避免方法很簡單,只要在ERROR_CODE中增加0的有效定義即可,例如比較正確形式的應該如下:

public enum ERROR_CODE

{

NO_ERROR = 0,

INVALID_FILE_NAME = 1001,

CANT_BE_ACCESS = 1002,

}

按照如上的做法就可以避免定義ERROR_CODE變量或者被組合到別的類型中的時候,都不會發生初始值是無效的尴尬局面。

在這本書中,對于枚舉類型還提到一點,就是增加Flags標記的時候,一定要以None作爲0,例如:

[Flags]

public enum Style

{

None = 0,

Flat = 1,

}

這樣的目的是爲了在與和或操作的時候能有意義。這方面的例子我就不多說了,例如:某個connection的狀態,或者文件的某種屬性等等都會用到類似的做法。

除了枚舉類型外,對于struct定義的值類型來說,如果struct類型所包含的成員類型都是值類型的話,是沒有什麽問題(如果是自定義枚舉類型,要參照上面所說的方法進行處理);但是如果包含引用類型,則需要進行初始化,避免在訪問的時候出現異常。例如對于前面所說的ErrorMsg來說,由于struct默認構造函數的存在,有可能在ErrorMsg類型變量在構造後,其的strMsg成員不是有效的。除了string類型外,常見的還有數組類型。如何避免類似的問題呢,方法是采用屬性來實現。例如:

public struct ErrorMsg

{

private ERROR_CODE err;

private string strMsg;

public string Message

{

get

{

if( strMsg == null ) return string.Empty;

else

return strMsg;

}

}

// other properties or methods here

}

public struct IntArray

{

private int[] nArray;

public int[] Array

{

get

{

if( nArray == null )

nArray = new int[10];

return nArray;

}

}

}

所以在論壇上經常看到有人提出不能在struct中定義一個固定維數的數組,那麽參照如上的方法,這類問題就能得到很好地解決。

最後再提一句,對于要確保“0”在所定義的值類型中是有效的這一點來說別小看。屏蔽錯誤從細微做起,而且好的編碼習慣會使後面的工作事半功倍。

大家在看了這標題後,肯定會覺的,爲什麽要確保“0”是有效的,這一點主要是跟值類型的內存分配有關,值類型有默認的構造函數,這是沒法避免的,因此值類型變量中的成員在初始化的時候所出現的細微問題(對于值類型這方面的知識可以參看我前面一篇文章)。 http://blog.csdn.net/Knight94/archive/2006/07/01/861383.aspx 日常中比較常見的兩種值類型,一個是enum定義的枚舉類型,一個是用struct定義的數據類型。那我接下來就分別說明這兩種類型如果不定義“0”爲一個有效值的所能造成的後果,再分別說明如何加以修改來彌補這類錯誤。 對于enum定義的枚舉類型來說,默認的起始值爲0,但是如果在定義的時候,按照如下的方式去定義的話,有時候會造成意想不到的錯誤。 public enum ERROR_CODE { INVALID_FILE_NAME = 1001, CANT_BE_ACCESS = 1002, } 如上的定義是沒有默認值0的,那麽當我顯示的去定義一個此類型變量,例如: ERROR_CODE myError = new ERROR_CODE(); Debug.WriteLine( string.Format( "{0}", (int)myError ) ); 可以看出如上的輸出結果是0,但是它不是一個有效的值,也許這種錯誤可能很少出現,但是在struct複合類型中這種錯誤表現得更爲明顯。例如: public struct ErrorMsg { private ERROR_CODE err; private string strMsg; // other properties or methods here } 對于如上的結構類型來說,由于默認構造函數存在,所以當創建一個ErrorMsg變量的時候,那麽對于err這個成員的值是無效的。有人可能會說,增加構造函數來限制等等的做法來避免這類錯誤。那麽爲什麽與其在ErrorMsg中增加限制,不如在定義ERROR_CODE的時候就避免呢。其實這類錯誤的避免方法很簡單,只要在ERROR_CODE中增加0的有效定義即可,例如比較正確形式的應該如下: public enum ERROR_CODE { NO_ERROR = 0, INVALID_FILE_NAME = 1001, CANT_BE_ACCESS = 1002, } 按照如上的做法就可以避免定義ERROR_CODE變量或者被組合到別的類型中的時候,都不會發生初始值是無效的尴尬局面。 在這本書中,對于枚舉類型還提到一點,就是增加Flags標記的時候,一定要以None作爲0,例如: [Flags] public enum Style { None = 0, Flat = 1, } 這樣的目的是爲了在與和或操作的時候能有意義。這方面的例子我就不多說了,例如:某個connection的狀態,或者文件的某種屬性等等都會用到類似的做法。 除了枚舉類型外,對于struct定義的值類型來說,如果struct類型所包含的成員類型都是值類型的話,是沒有什麽問題(如果是自定義枚舉類型,要參照上面所說的方法進行處理);但是如果包含引用類型,則需要進行初始化,避免在訪問的時候出現異常。例如對于前面所說的ErrorMsg來說,由于struct默認構造函數的存在,有可能在ErrorMsg類型變量在構造後,其的strMsg成員不是有效的。除了string類型外,常見的還有數組類型。如何避免類似的問題呢,方法是采用屬性來實現。例如: public struct ErrorMsg { private ERROR_CODE err; private string strMsg; public string Message { get { if( strMsg == null ) return string.Empty; else return strMsg; } } // other properties or methods here } public struct IntArray { private int[] nArray; public int[] Array { get { if( nArray == null ) nArray = new int[10]; return nArray; } } } 所以在論壇上經常看到有人提出不能在struct中定義一個固定維數的數組,那麽參照如上的方法,這類問題就能得到很好地解決。 最後再提一句,對于要確保“0”在所定義的值類型中是有效的這一點來說別小看。屏蔽錯誤從細微做起,而且好的編碼習慣會使後面的工作事半功倍。
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
王朝網路微信公眾號
微信掃碼關註本站公眾號 wangchaonetcn
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有