Разработка полей
Обновлен: Ноябрь 2007
Поля содержат данные, связанные с объектом. В большинстве сценариев любые нестатические поля в библиотеке не должны быть видимы для разработчиков. Следующие рекомендации помогут правильно использовать поля при разработке библиотеки.
Не следует предоставлять публичные или защищенные поля экземпляра.
Публичные и защищенные поля плохо переносятся из версии в версию и не защищены требованиями управления доступом для кода. Вместо публично видимых полей рекомендуется использовать личные поля и обеспечивать доступ к ним через свойства.
Для значений, которые никогда не изменяются, используйте поля констант.
Например, класс Math определяет E и PI как статические константы.
Компилятор вставляет код инициализации полей const непосредственно в код вызова; это означает, что значения const никогда не будут изменены и не возникнет проблем совместимости.
Для предварительно определенных экземпляров объекта следует использовать публичные статические поля, доступные только для чтения.
Например, класс DateTime обеспечивает статические поля, доступные только для чтения, которые можно использовать для получения объектов DateTime, которые установлены в максимальное или минимальное значение времени. См. MaxValue и MinValue.
Не назначайте экземпляры изменяемых типов полям, доступным только для чтения.
Объекты, созданные с использованием изменяющегося типа, можно модифицировать после их создания. Например, массивы и большинство коллекций являются изменяющимися типами, в то время как Int32, Uri и String являются неизменяющимися типами. Для полей, содержащих изменяющийся ссылочный тип, модификатор "read-only" предотвращает перезапись значения поля, но не защищает изменяющийся тип от модификации.
Следующий пример кода демонстрирует проблему, возникающую при использовании полей с модификатором "read-only". Класс BadDesign создает поле с модификатором "read-only" и предоставляет его только для чтения. Это не предотвращает модификацию содержимого поля с модификатором "read-only" в классе 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();
}
}
}
Охраняется авторским правом Copyright 2005 Microsoft Corporation. Все права защищены.
Охраняется авторским правом Copyright Addison-Wesley Corporation. Все права защищены.
Дополнительные сведения о руководствах по разработке см. в книге "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries", Krzysztof Cwalina and Brad Abrams, Addison-Wesley, 2005.