更新 : 2007 年 11 月
フィールドは、オブジェクトに関連付けらたデータを保持します。ほとんどのシナリオで、ライブラリの非静的フィールドは、開発者に対して参照可能にしないでください。以下のガイドラインに従うと、ライブラリのデザインでフィールドを正しく使用できます。
パブリックまたは保護されたインスタンス フィールドは提供しないでください。
パブリック フィールドとプロテクト フィールドは適切にバージョン管理されず、またコード アクセス セキュリティ要求によって保護されません。パブリックに参照可能なフィールドを使用する代わりにプライベート フィールドを使用し、それをプロパティを通じて公開してください。
変更されない定数には、定数フィールドを使用してください。
たとえば、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();
}
}
}
Portions Copyright 2005 Microsoft Corporation.All rights reserved.
Portions Copyright Addison-Wesley Corporation.All rights reserved.
デザイン ガイドラインの詳細については、2005 年に Addison-Wesley から出版されている Krzysztof Cwalina、Brad Abrams 共著の『Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries』を参照してください。