フィールドのデザイン
フィールドは、オブジェクトに関連付けらたデータを保持します。 ほとんどのシナリオで、ライブラリの非静的フィールドは、開発者に対して参照可能にしないでください。 以下のガイドラインに従うと、ライブラリのデザインでフィールドを正しく使用できます。
パブリックまたは保護されたインスタンス フィールドは提供しないでください。
パブリック フィールドとプロテクト フィールドは適切にバージョン管理されず、またコード アクセス セキュリティ要求によって保護されません。 パブリックに参照可能なフィールドを使用する代わりにプライベート フィールドを使用し、それをプロパティを通じて公開してください。
変更されない定数には、定数フィールドを使用してください。
たとえば、Math クラスでは、E と PI を静的定数として定義します。
コンパイラは、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.
設計ガイドラインの詳細についてを参照してください、「フレームワークの設計ガイドライン。規則、慣用句、および再利用可能なパターン。ネット ライブラリ」本クシシュトフ Cwalina、ブラッド エイブラムス、アスキー、2005 年発表しました。