字段设计
字段保存对象的关联数据。 在大多数情况下,库中的所有非静态字段对开发人员都应是不可见的。 下面的准则有助于在库设计中正确使用字段。
不要提供公共的或受保护的实例字段。
公共字段和受保护字段未经版本控制,不受代码访问安全性要求的保护。 使用私有字段,并通过属性公开这些私有字段,而不要使用公共可见字段。
对不会更改的常数使用常数字段。
编译器将 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();
}
};
}}}
部分版权所有 2005 Microsoft Corporation。 保留所有权利。
部分版权所有 Addison-Wesley Corporation。 保留所有权利。
设计指引的详细信息,请参阅"框架设计准则: 公约、 成语和可重复使用的模式。网络图书馆"书 Krzysztof Cwalina 和布拉德 · 艾布拉姆斯,2005年艾迪生 - 韦斯利,发表。