欄位設計
欄位可保存與物件有關的資料。 在大多數的情況下,程式庫中的任何非靜態欄位應該不會讓開發人員看到。 下列方針可協助您在程式庫設計中正確使用欄位。
不要提供公用或受保護的執行個體欄位。
公用和受保護的欄位在版本控制上並不理想,因此不受程式碼存取安全性要求的保護。 請不要使用公開可見的欄位,而是要使用私用欄位,並透過屬性來進行公開。
要針對絕對不會變更的常數使用常數欄位。
編譯器會將 const 欄位的值直接插入呼叫程式碼中,這表示在變更 const 值時,一定會遇到引入相容性問題所帶來的風險。
一定要針對預先定義的物件執行個體使用公用靜態唯讀欄位。
例如,DateTime 類別會提供靜態唯讀欄位,您可使用此欄位來取得設定為最大或最小時間值的 DateTime 物件。 請參閱MaxValue和MinValue。
請不要將可變動型別的執行個體指派給唯讀欄位。
使用可變動型別建立的物件可以在建立之後修改。 例如,陣列和大多數集合都是可變動型別,而 Int32, Uri 和 String 則是不可變動型別。 對於保存可變動參考型別的欄位而言,唯讀修飾詞可避免欄位值被覆寫,但是並不會防止可變動型別被修改。
下列程式碼範例將示範使用唯讀欄位的問題。 BadDesign 類別會建立唯讀欄位,並使用唯讀屬性將它公開。 這不會防止 ShowBadDesign 類別修改唯讀欄位的內容。
Imports System
Namespace Examples.DesignGuidelines.Fields
Public Class BadDesign
Public Readonly dataValues as Integer() = {1,2,3}
Public ReadOnly Property Data as Integer ()
Get
Return dataValues
End Get
End Property
Public Sub WriteData()
For Each i as Integer In dataValues
Console.Write ("{0} ", i)
Next i
Console.WriteLine()
End Sub
End Class
Public Class ShowBadDesign
Public Shared Sub Main()
Dim bad as BadDesign = new BadDesign()
' The following line will write: 1 2 3
bad.WriteData()
Dim badData as Integer() = bad.Data
For i as Integer = 0 To badData.Length -1
badData(i) = 0
Next i
' The following line will write: 0 0 0
' because bad's data has been modified.
bad.WriteData()
End Sub
End Class
End Namespace
using System;
namespace Examples.DesignGuidelines.Fields
{
public class BadDesign
{
public readonly int[] data = {1,2,3};
public int [] Data
{
get {return data;}
}
public void WriteData()
{
foreach (int i in data)
{
Console.Write ("{0} ", i);
}
Console.WriteLine();
}
}
public class ShowBadDesign
{
public static void Main()
{
BadDesign bad = new BadDesign();
// The following line will write: 1 2 3
bad.WriteData();
int[] badData = bad.Data;
for (int i = 0; i< badData.Length; i++)
{
badData[i] = 0;
}
// The following line will write: 0 0 0
// because bad's data has been modified.
bad.WriteData();
}
}
}
using namespace System;
namespace Examples { namespace DesignGuidelines { namespace Fields
{
public ref class BadDesign
{
public:
static const array<int>^ data = {1,2,3};
property array<int>^ Data
{
array<int>^ get() {return data;}
}
void WriteData()
{
for each (int i in data)
{
Console::Write ("{0} ", i);
}
Console::WriteLine();
}
};
public ref class ShowBadDesign
{
public:
static void Main()
{
BadDesign^ bad = gcnew BadDesign();
// The following line will write: 1 2 3
bad->WriteData();
array<int>^ badData = bad->Data;
for (int i = 0; i< badData->Length; i++)
{
badData[i] = 0;
}
// The following line will write: 0 0 0
// because bad's data has been modified.
bad->WriteData();
}
};
}}}
Portions Copyright 2005 Microsoft Corporation. All rights reserved.
Portions Copyright Addison-Wesley Corporation. All rights reserved.
設計指引的詳細資訊,請參閱"框架設計準則:公約、 成語和可重複使用的模式。網路圖書館"書 Krzysztof Cwalina 和布拉德 · 艾布拉姆斯,2005年艾迪生 - 衛斯理,發表。